Logging.m
author Jens Alfke <jens@mooseyard.com>
Sat May 17 13:14:48 2008 -0700 (2008-05-17)
changeset 9 823e7e74088e
parent 0 d84d25d6cdbb
child 11 e5976864dfe9
permissions -rw-r--r--
* Assert macros now put the failure code in a separate segment.
* Added $string utility.
jens@0
     1
//
jens@0
     2
//  Logging.m
jens@0
     3
//  MYUtilities
jens@0
     4
//
jens@0
     5
//  Created by Jens Alfke on 1/5/08.
jens@0
     6
//  Copyright 2008 Jens Alfke. All rights reserved.
jens@0
     7
//
jens@0
     8
jens@0
     9
#import "Logging.h"
jens@0
    10
#import <unistd.h>
jens@0
    11
#include <fcntl.h>
jens@0
    12
#include <sys/param.h>
jens@0
    13
jens@0
    14
jens@0
    15
NSString* LOC( NSString *key )     // Localized string lookup
jens@0
    16
{
jens@0
    17
    NSString *value = [[NSBundle mainBundle] localizedStringForKey:key value:nil table:nil];
jens@0
    18
    if( value == key ) {
jens@0
    19
        Warn(@"No localized string for '%@' in Localizable.strings!",key);
jens@0
    20
        value = [key uppercaseString];
jens@0
    21
    }
jens@0
    22
    return value;
jens@0
    23
}
jens@0
    24
jens@0
    25
jens@1
    26
int _gShouldLog = -1;
jens@1
    27
static BOOL sConsole;
jens@1
    28
static NSMutableSet *sEnabledDomains;
jens@0
    29
jens@0
    30
jens@0
    31
static BOOL isConsole( int fd )
jens@0
    32
{
jens@0
    33
    if( isatty(fd) )
jens@0
    34
        return YES;
jens@0
    35
    char path[MAXPATHLEN];
jens@0
    36
    if( fcntl(fd, F_GETPATH, path) == -1 )
jens@0
    37
        return NO;
jens@0
    38
    return YES;
jens@0
    39
}
jens@0
    40
jens@0
    41
jens@1
    42
static void InitLogging()
jens@0
    43
{
jens@1
    44
    if( _gShouldLog != -1 )
jens@1
    45
        return;
jens@1
    46
jens@1
    47
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
jens@1
    48
    _gShouldLog = NO;
jens@1
    49
    sEnabledDomains = [[NSMutableSet alloc] init];
jens@1
    50
    NSDictionary *dflts = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
jens@1
    51
    for( NSString *key in dflts ) {
jens@1
    52
        if( [key hasPrefix: @"Log"] ) {
jens@1
    53
            BOOL value = [[NSUserDefaults standardUserDefaults] boolForKey: key];
jens@1
    54
            if( key.length==3 )
jens@1
    55
                _gShouldLog = value;
jens@1
    56
            else if( value )
jens@1
    57
                [sEnabledDomains addObject: [key substringFromIndex: 3]];
jens@1
    58
        }
jens@1
    59
    }
jens@1
    60
    sConsole = isConsole(STDERR_FILENO);
jens@1
    61
    
jens@1
    62
    Log(@"Logging enabled in domains: {%@}", 
jens@1
    63
        [[[sEnabledDomains allObjects] sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)] 
jens@1
    64
                componentsJoinedByString: @", "]);
jens@1
    65
    [pool drain];
jens@1
    66
}
jens@1
    67
jens@1
    68
jens@1
    69
BOOL EnableLog( BOOL enable )
jens@1
    70
{
jens@1
    71
    if( _gShouldLog == -1 )
jens@1
    72
        InitLogging();
jens@1
    73
    BOOL old = _gShouldLog;
jens@1
    74
    _gShouldLog = enable;
jens@1
    75
    return old;
jens@1
    76
}
jens@1
    77
jens@1
    78
BOOL _WillLogTo( NSString *domain )
jens@1
    79
{
jens@1
    80
    if( _gShouldLog == -1 )
jens@1
    81
        InitLogging();
jens@1
    82
    return _gShouldLog && [sEnabledDomains containsObject: domain];
jens@1
    83
}
jens@1
    84
jens@1
    85
BOOL _EnableLogTo( NSString *domain, BOOL enable )
jens@1
    86
{
jens@1
    87
    if( _gShouldLog == -1 )
jens@1
    88
        InitLogging();
jens@1
    89
    BOOL old = [sEnabledDomains containsObject: domain];
jens@1
    90
    if( enable )
jens@1
    91
        [sEnabledDomains addObject: domain];
jens@1
    92
    else
jens@1
    93
        [sEnabledDomains removeObject: domain];
jens@1
    94
    return old;
jens@1
    95
}
jens@1
    96
jens@1
    97
jens@1
    98
static void _Logv( NSString *prefix, NSString *msg, va_list args )
jens@1
    99
{
jens@1
   100
    if( sConsole ) {
jens@0
   101
        NSAutoreleasePool *pool = [NSAutoreleasePool new];
jens@0
   102
        static NSDateFormatter *sTimestampFormat;
jens@0
   103
        if( ! sTimestampFormat ) {
jens@0
   104
            sTimestampFormat = [[NSDateFormatter alloc] init];
jens@0
   105
            sTimestampFormat.dateFormat = @"HH:mm:ss.SSS";
jens@0
   106
        }
jens@0
   107
        NSDate *now = [[NSDate alloc] init];
jens@0
   108
        NSString *timestamp = [sTimestampFormat stringFromDate: now];
jens@0
   109
        [now release];
jens@1
   110
        NSString *separator = prefix.length ?@": " :@"";
jens@0
   111
        msg = [[NSString alloc] initWithFormat: msg arguments: args];
jens@1
   112
        NSString *finalMsg = [[NSString alloc] initWithFormat: @"%@| %@%@%@\n", 
jens@1
   113
                              timestamp,prefix,separator,msg];
jens@0
   114
        fputs([finalMsg UTF8String], stderr);
jens@0
   115
        [finalMsg release];
jens@0
   116
        [msg release];
jens@0
   117
        [pool drain];
jens@0
   118
    } else
jens@0
   119
        NSLogv(msg,args);
jens@0
   120
}
jens@0
   121
jens@0
   122
jens@0
   123
void AlwaysLog( NSString *msg, ... )
jens@0
   124
{
jens@0
   125
    va_list args;
jens@0
   126
    va_start(args,msg);
jens@1
   127
    _Logv(@"",msg,args);
jens@0
   128
    va_end(args);
jens@0
   129
}
jens@0
   130
jens@0
   131
jens@0
   132
void _Log( NSString *msg, ... )
jens@0
   133
{
jens@1
   134
    if( _gShouldLog == -1 )
jens@1
   135
        InitLogging();
jens@1
   136
    if( _gShouldLog ) {
jens@0
   137
        va_list args;
jens@0
   138
        va_start(args,msg);
jens@1
   139
        _Logv(@"",msg,args);
jens@0
   140
        va_end(args);
jens@0
   141
    }
jens@0
   142
}
jens@0
   143
jens@0
   144
jens@1
   145
void _LogTo( NSString *domain, NSString *msg, ... )
jens@1
   146
{
jens@1
   147
    if( _gShouldLog == -1 )
jens@1
   148
        InitLogging();
jens@1
   149
    if( _gShouldLog && [sEnabledDomains containsObject: domain] ) {
jens@1
   150
        va_list args;
jens@1
   151
        va_start(args,msg);
jens@1
   152
        _Logv(domain, msg, args);
jens@1
   153
        va_end(args);
jens@1
   154
    }
jens@1
   155
}
jens@1
   156
jens@1
   157
jens@0
   158
void Warn( NSString *msg, ... )
jens@0
   159
{
jens@0
   160
    va_list args;
jens@0
   161
    va_start(args,msg);
jens@1
   162
    _Logv(@"WARNING*** ",msg,args);
jens@0
   163
    va_end(args);
jens@0
   164
}
jens@0
   165
jens@0
   166