jens@0: // jens@0: // Logging.m jens@0: // MYUtilities jens@0: // jens@0: // Created by Jens Alfke on 1/5/08. jens@0: // Copyright 2008 Jens Alfke. All rights reserved. jens@0: // jens@0: jens@0: #import "Logging.h" jens@0: #import jens@0: #include jens@0: #include jens@0: jens@0: jens@0: NSString* LOC( NSString *key ) // Localized string lookup jens@0: { jens@0: NSString *value = [[NSBundle mainBundle] localizedStringForKey:key value:nil table:nil]; jens@0: if( value == key ) { jens@0: Warn(@"No localized string for '%@' in Localizable.strings!",key); jens@0: value = [key uppercaseString]; jens@0: } jens@0: return value; jens@0: } jens@0: jens@0: jens@1: int _gShouldLog = -1; jens@1: static BOOL sConsole; jens@1: static NSMutableSet *sEnabledDomains; jens@0: jens@0: jens@0: static BOOL isConsole( int fd ) jens@0: { jens@0: if( isatty(fd) ) jens@0: return YES; jens@0: char path[MAXPATHLEN]; jens@0: if( fcntl(fd, F_GETPATH, path) == -1 ) jens@0: return NO; jens@0: return YES; jens@0: } jens@0: jens@0: jens@1: static void InitLogging() jens@0: { jens@1: if( _gShouldLog != -1 ) jens@1: return; jens@1: jens@1: NSAutoreleasePool *pool = [NSAutoreleasePool new]; jens@1: _gShouldLog = NO; jens@1: sEnabledDomains = [[NSMutableSet alloc] init]; jens@1: NSDictionary *dflts = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; jens@1: for( NSString *key in dflts ) { jens@1: if( [key hasPrefix: @"Log"] ) { jens@1: BOOL value = [[NSUserDefaults standardUserDefaults] boolForKey: key]; jens@1: if( key.length==3 ) jens@1: _gShouldLog = value; jens@1: else if( value ) jens@1: [sEnabledDomains addObject: [key substringFromIndex: 3]]; jens@1: } jens@1: } jens@1: sConsole = isConsole(STDERR_FILENO); jens@1: jens@1: Log(@"Logging enabled in domains: {%@}", jens@1: [[[sEnabledDomains allObjects] sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)] jens@1: componentsJoinedByString: @", "]); jens@1: [pool drain]; jens@1: } jens@1: jens@1: jens@1: BOOL EnableLog( BOOL enable ) jens@1: { jens@1: if( _gShouldLog == -1 ) jens@1: InitLogging(); jens@1: BOOL old = _gShouldLog; jens@1: _gShouldLog = enable; jens@1: return old; jens@1: } jens@1: jens@1: BOOL _WillLogTo( NSString *domain ) jens@1: { jens@1: if( _gShouldLog == -1 ) jens@1: InitLogging(); jens@1: return _gShouldLog && [sEnabledDomains containsObject: domain]; jens@1: } jens@1: jens@1: BOOL _EnableLogTo( NSString *domain, BOOL enable ) jens@1: { jens@1: if( _gShouldLog == -1 ) jens@1: InitLogging(); jens@1: BOOL old = [sEnabledDomains containsObject: domain]; jens@1: if( enable ) jens@1: [sEnabledDomains addObject: domain]; jens@1: else jens@1: [sEnabledDomains removeObject: domain]; jens@1: return old; jens@1: } jens@1: jens@1: jens@1: static void _Logv( NSString *prefix, NSString *msg, va_list args ) jens@1: { jens@1: if( sConsole ) { jens@0: NSAutoreleasePool *pool = [NSAutoreleasePool new]; jens@0: static NSDateFormatter *sTimestampFormat; jens@0: if( ! sTimestampFormat ) { jens@0: sTimestampFormat = [[NSDateFormatter alloc] init]; jens@0: sTimestampFormat.dateFormat = @"HH:mm:ss.SSS"; jens@0: } jens@0: NSDate *now = [[NSDate alloc] init]; jens@0: NSString *timestamp = [sTimestampFormat stringFromDate: now]; jens@0: [now release]; jens@1: NSString *separator = prefix.length ?@": " :@""; jens@0: msg = [[NSString alloc] initWithFormat: msg arguments: args]; jens@1: NSString *finalMsg = [[NSString alloc] initWithFormat: @"%@| %@%@%@\n", jens@1: timestamp,prefix,separator,msg]; jens@0: fputs([finalMsg UTF8String], stderr); jens@0: [finalMsg release]; jens@0: [msg release]; jens@0: [pool drain]; jens@0: } else jens@0: NSLogv(msg,args); jens@0: } jens@0: jens@0: jens@0: void AlwaysLog( NSString *msg, ... ) jens@0: { jens@0: va_list args; jens@0: va_start(args,msg); jens@1: _Logv(@"",msg,args); jens@0: va_end(args); jens@0: } jens@0: jens@0: jens@0: void _Log( NSString *msg, ... ) jens@0: { jens@1: if( _gShouldLog == -1 ) jens@1: InitLogging(); jens@1: if( _gShouldLog ) { jens@0: va_list args; jens@0: va_start(args,msg); jens@1: _Logv(@"",msg,args); jens@0: va_end(args); jens@0: } jens@0: } jens@0: jens@0: jens@1: void _LogTo( NSString *domain, NSString *msg, ... ) jens@1: { jens@1: if( _gShouldLog == -1 ) jens@1: InitLogging(); jens@1: if( _gShouldLog && [sEnabledDomains containsObject: domain] ) { jens@1: va_list args; jens@1: va_start(args,msg); jens@1: _Logv(domain, msg, args); jens@1: va_end(args); jens@1: } jens@1: } jens@1: jens@1: jens@0: void Warn( NSString *msg, ... ) jens@0: { jens@0: va_list args; jens@0: va_start(args,msg); jens@1: _Logv(@"WARNING*** ",msg,args); jens@0: va_end(args); jens@0: } jens@0: jens@0: