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 16 static int g_debug = 0; 17 static 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 29 uint32_t g_log_bits = 0; 30 static DNBCallbackLog g_log_callback = NULL; 31 static void *g_log_baton = NULL; 32 33 34 int 35 DNBLogGetDebug () 36 { 37 return g_debug; 38 } 39 40 41 void 42 DNBLogSetDebug (int g) 43 { 44 g_debug = g; 45 } 46 47 int 48 DNBLogGetVerbose () 49 { 50 return g_verbose; 51 } 52 53 void 54 DNBLogSetVerbose (int v) 55 { 56 g_verbose = v; 57 } 58 59 bool 60 DNBLogCheckLogBit (uint32_t bit) 61 { 62 return (g_log_bits & bit) != 0; 63 } 64 65 uint32_t 66 DNBLogSetLogMask (uint32_t mask) 67 { 68 uint32_t old = g_log_bits; 69 g_log_bits = mask; 70 return old; 71 } 72 73 uint32_t 74 DNBLogGetLogMask () 75 { 76 return g_log_bits; 77 } 78 79 void 80 DNBLogSetLogCallback (DNBCallbackLog callback, void *baton) 81 { 82 g_log_callback = callback; 83 g_log_baton = baton; 84 } 85 86 bool 87 DNBLogEnabled () 88 { 89 return g_log_callback != NULL; 90 } 91 92 static 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 99 void 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 //---------------------------------------------------------------------- 112 void 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 //---------------------------------------------------------------------- 129 void 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 142 static pthread_mutex_t * 143 GetLogThreadedMutex() 144 { 145 static PThreadMutex g_LogThreadedMutex(PTHREAD_MUTEX_RECURSIVE); 146 return g_LogThreadedMutex.Mutex(); 147 } 148 static 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 //---------------------------------------------------------------------- 154 void 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 //---------------------------------------------------------------------- 179 void 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 //---------------------------------------------------------------------- 205 void 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 //---------------------------------------------------------------------- 228 void 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 //---------------------------------------------------------------------- 253 void 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 //---------------------------------------------------------------------- 269 void 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 //---------------------------------------------------------------------- 290 void 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