toolkit/crashreporter/google-breakpad/src/common/mac/GTMLogger.m

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/crashreporter/google-breakpad/src/common/mac/GTMLogger.m	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,612 @@
     1.4 +//
     1.5 +//  GTMLogger.m
     1.6 +//
     1.7 +//  Copyright 2007-2008 Google Inc.
     1.8 +//
     1.9 +//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
    1.10 +//  use this file except in compliance with the License.  You may obtain a copy
    1.11 +//  of the License at
    1.12 +//
    1.13 +//  http://www.apache.org/licenses/LICENSE-2.0
    1.14 +//
    1.15 +//  Unless required by applicable law or agreed to in writing, software
    1.16 +//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    1.17 +//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
    1.18 +//  License for the specific language governing permissions and limitations under
    1.19 +//  the License.
    1.20 +//
    1.21 +
    1.22 +#import "GTMLogger.h"
    1.23 +#import "GTMGarbageCollection.h"
    1.24 +#import <fcntl.h>
    1.25 +#import <unistd.h>
    1.26 +#import <stdlib.h>
    1.27 +#import <pthread.h>
    1.28 +
    1.29 +
    1.30 +#if !defined(__clang__) && (__GNUC__*10+__GNUC_MINOR__ >= 42)
    1.31 +// Some versions of GCC (4.2 and below AFAIK) aren't great about supporting
    1.32 +// -Wmissing-format-attribute
    1.33 +// when the function is anything more complex than foo(NSString *fmt, ...).
    1.34 +// You see the error inside the function when you turn ... into va_args and
    1.35 +// attempt to call another function (like vsprintf for example).
    1.36 +// So we just shut off the warning for this file. We reenable it at the end.
    1.37 +#pragma GCC diagnostic ignored "-Wmissing-format-attribute"
    1.38 +#endif  // !__clang__
    1.39 +
    1.40 +// Reference to the shared GTMLogger instance. This is not a singleton, it's
    1.41 +// just an easy reference to one shared instance.
    1.42 +static GTMLogger *gSharedLogger = nil;
    1.43 +
    1.44 +
    1.45 +@implementation GTMLogger
    1.46 +
    1.47 +// Returns a pointer to the shared logger instance. If none exists, a standard
    1.48 +// logger is created and returned.
    1.49 ++ (id)sharedLogger {
    1.50 +  @synchronized(self) {
    1.51 +    if (gSharedLogger == nil) {
    1.52 +      gSharedLogger = [[self standardLogger] retain];
    1.53 +    }
    1.54 +  }
    1.55 +  return [[gSharedLogger retain] autorelease];
    1.56 +}
    1.57 +
    1.58 ++ (void)setSharedLogger:(GTMLogger *)logger {
    1.59 +  @synchronized(self) {
    1.60 +    [gSharedLogger autorelease];
    1.61 +    gSharedLogger = [logger retain];
    1.62 +  }
    1.63 +}
    1.64 +
    1.65 ++ (id)standardLogger {
    1.66 +  // Don't trust NSFileHandle not to throw
    1.67 +  @try {
    1.68 +    id<GTMLogWriter> writer = [NSFileHandle fileHandleWithStandardOutput];
    1.69 +    id<GTMLogFormatter> fr = [[[GTMLogStandardFormatter alloc] init]
    1.70 +                                 autorelease];
    1.71 +    id<GTMLogFilter> filter = [[[GTMLogLevelFilter alloc] init] autorelease];
    1.72 +    return [[[self alloc] initWithWriter:writer
    1.73 +                               formatter:fr
    1.74 +                                  filter:filter] autorelease];
    1.75 +  }
    1.76 +  @catch (id e) {
    1.77 +    // Ignored
    1.78 +  }
    1.79 +  return nil;
    1.80 +}
    1.81 +
    1.82 ++ (id)standardLoggerWithStderr {
    1.83 +  // Don't trust NSFileHandle not to throw
    1.84 +  @try {
    1.85 +    id me = [self standardLogger];
    1.86 +    [me setWriter:[NSFileHandle fileHandleWithStandardError]];
    1.87 +    return me;
    1.88 +  }
    1.89 +  @catch (id e) {
    1.90 +    // Ignored
    1.91 +  }
    1.92 +  return nil;
    1.93 +}
    1.94 +
    1.95 ++ (id)standardLoggerWithStdoutAndStderr {
    1.96 +  // We're going to take advantage of the GTMLogger to GTMLogWriter adaptor
    1.97 +  // and create a composite logger that an outer "standard" logger can use
    1.98 +  // as a writer. Our inner loggers should apply no formatting since the main
    1.99 +  // logger does that and we want the caller to be able to change formatters
   1.100 +  // or add writers without knowing the inner structure of our composite.
   1.101 +
   1.102 +  // Don't trust NSFileHandle not to throw
   1.103 +  @try {
   1.104 +    GTMLogBasicFormatter *formatter = [[[GTMLogBasicFormatter alloc] init] 
   1.105 +                                          autorelease];
   1.106 +    GTMLogger *stdoutLogger =
   1.107 +        [self loggerWithWriter:[NSFileHandle fileHandleWithStandardOutput]
   1.108 +                     formatter:formatter
   1.109 +                        filter:[[[GTMLogMaximumLevelFilter alloc]
   1.110 +                                  initWithMaximumLevel:kGTMLoggerLevelInfo]
   1.111 +                                      autorelease]];
   1.112 +    GTMLogger *stderrLogger =
   1.113 +        [self loggerWithWriter:[NSFileHandle fileHandleWithStandardError]
   1.114 +                     formatter:formatter
   1.115 +                        filter:[[[GTMLogMininumLevelFilter alloc]
   1.116 +                                  initWithMinimumLevel:kGTMLoggerLevelError]
   1.117 +                                      autorelease]];
   1.118 +    GTMLogger *compositeWriter =
   1.119 +        [self loggerWithWriter:[NSArray arrayWithObjects:
   1.120 +                                   stdoutLogger, stderrLogger, nil]
   1.121 +                     formatter:formatter
   1.122 +                        filter:[[[GTMLogNoFilter alloc] init] autorelease]];
   1.123 +    GTMLogger *outerLogger = [self standardLogger];
   1.124 +    [outerLogger setWriter:compositeWriter];
   1.125 +    return outerLogger;
   1.126 +  }
   1.127 +  @catch (id e) {
   1.128 +    // Ignored
   1.129 +  }
   1.130 +  return nil;
   1.131 +}
   1.132 +
   1.133 ++ (id)standardLoggerWithPath:(NSString *)path {
   1.134 +  @try {
   1.135 +    NSFileHandle *fh = [NSFileHandle fileHandleForLoggingAtPath:path mode:0644];
   1.136 +    if (fh == nil) return nil;
   1.137 +    id me = [self standardLogger];
   1.138 +    [me setWriter:fh];
   1.139 +    return me;
   1.140 +  }
   1.141 +  @catch (id e) {
   1.142 +    // Ignored
   1.143 +  }
   1.144 +  return nil;
   1.145 +}
   1.146 +
   1.147 ++ (id)loggerWithWriter:(id<GTMLogWriter>)writer
   1.148 +             formatter:(id<GTMLogFormatter>)formatter
   1.149 +                filter:(id<GTMLogFilter>)filter {
   1.150 +  return [[[self alloc] initWithWriter:writer
   1.151 +                             formatter:formatter
   1.152 +                                filter:filter] autorelease];
   1.153 +}
   1.154 +
   1.155 ++ (id)logger {
   1.156 +  return [[[self alloc] init] autorelease];
   1.157 +}
   1.158 +
   1.159 +- (id)init {
   1.160 +  return [self initWithWriter:nil formatter:nil filter:nil];
   1.161 +}
   1.162 +
   1.163 +- (id)initWithWriter:(id<GTMLogWriter>)writer
   1.164 +           formatter:(id<GTMLogFormatter>)formatter
   1.165 +              filter:(id<GTMLogFilter>)filter {
   1.166 +  if ((self = [super init])) {
   1.167 +    [self setWriter:writer];
   1.168 +    [self setFormatter:formatter];
   1.169 +    [self setFilter:filter];
   1.170 +  }
   1.171 +  return self;
   1.172 +}
   1.173 +
   1.174 +- (void)dealloc {
   1.175 +  // Unlikely, but |writer_| may be an NSFileHandle, which can throw
   1.176 +  @try {
   1.177 +    [formatter_ release];
   1.178 +    [filter_ release];
   1.179 +    [writer_ release];
   1.180 +  }
   1.181 +  @catch (id e) {
   1.182 +    // Ignored
   1.183 +  }
   1.184 +  [super dealloc];
   1.185 +}
   1.186 +
   1.187 +- (id<GTMLogWriter>)writer {
   1.188 +  return [[writer_ retain] autorelease];
   1.189 +}
   1.190 +
   1.191 +- (void)setWriter:(id<GTMLogWriter>)writer {
   1.192 +  @synchronized(self) {
   1.193 +    [writer_ autorelease];
   1.194 +    writer_ = nil;
   1.195 +    if (writer == nil) {
   1.196 +      // Try to use stdout, but don't trust NSFileHandle
   1.197 +      @try {
   1.198 +        writer_ = [[NSFileHandle fileHandleWithStandardOutput] retain];
   1.199 +      }
   1.200 +      @catch (id e) {
   1.201 +        // Leave |writer_| nil
   1.202 +      }
   1.203 +    } else {
   1.204 +      writer_ = [writer retain];
   1.205 +    }
   1.206 +  }
   1.207 +}
   1.208 +
   1.209 +- (id<GTMLogFormatter>)formatter {
   1.210 +  return [[formatter_ retain] autorelease];
   1.211 +}
   1.212 +
   1.213 +- (void)setFormatter:(id<GTMLogFormatter>)formatter {
   1.214 +  @synchronized(self) {
   1.215 +    [formatter_ autorelease];
   1.216 +    formatter_ = nil;
   1.217 +    if (formatter == nil) {
   1.218 +      @try {
   1.219 +        formatter_ = [[GTMLogBasicFormatter alloc] init];
   1.220 +      }
   1.221 +      @catch (id e) {
   1.222 +        // Leave |formatter_| nil
   1.223 +      }
   1.224 +    } else {
   1.225 +      formatter_ = [formatter retain];
   1.226 +    }
   1.227 +  }
   1.228 +}
   1.229 +
   1.230 +- (id<GTMLogFilter>)filter {
   1.231 +  return [[filter_ retain] autorelease];
   1.232 +}
   1.233 +
   1.234 +- (void)setFilter:(id<GTMLogFilter>)filter {
   1.235 +  @synchronized(self) {
   1.236 +    [filter_ autorelease];
   1.237 +    filter_ = nil;
   1.238 +    if (filter == nil) {
   1.239 +      @try {
   1.240 +        filter_ = [[GTMLogNoFilter alloc] init];
   1.241 +      }
   1.242 +      @catch (id e) {
   1.243 +        // Leave |filter_| nil
   1.244 +      }
   1.245 +    } else {
   1.246 +      filter_ = [filter retain];
   1.247 +    }
   1.248 +  }
   1.249 +}
   1.250 +
   1.251 +- (void)logDebug:(NSString *)fmt, ... {
   1.252 +  va_list args;
   1.253 +  va_start(args, fmt);
   1.254 +  [self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelDebug];
   1.255 +  va_end(args);
   1.256 +}
   1.257 +
   1.258 +- (void)logInfo:(NSString *)fmt, ... {
   1.259 +  va_list args;
   1.260 +  va_start(args, fmt);
   1.261 +  [self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelInfo];
   1.262 +  va_end(args);
   1.263 +}
   1.264 +
   1.265 +- (void)logError:(NSString *)fmt, ... {
   1.266 +  va_list args;
   1.267 +  va_start(args, fmt);
   1.268 +  [self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelError];
   1.269 +  va_end(args);
   1.270 +}
   1.271 +
   1.272 +- (void)logAssert:(NSString *)fmt, ... {
   1.273 +  va_list args;
   1.274 +  va_start(args, fmt);
   1.275 +  [self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelAssert];
   1.276 +  va_end(args);
   1.277 +}
   1.278 +
   1.279 +@end  // GTMLogger
   1.280 +
   1.281 +@implementation GTMLogger (GTMLoggerMacroHelpers)
   1.282 +
   1.283 +- (void)logFuncDebug:(const char *)func msg:(NSString *)fmt, ... {
   1.284 +  va_list args;
   1.285 +  va_start(args, fmt);
   1.286 +  [self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelDebug];
   1.287 +  va_end(args);
   1.288 +}
   1.289 +
   1.290 +- (void)logFuncInfo:(const char *)func msg:(NSString *)fmt, ... {
   1.291 +  va_list args;
   1.292 +  va_start(args, fmt);
   1.293 +  [self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelInfo];
   1.294 +  va_end(args);
   1.295 +}
   1.296 +
   1.297 +- (void)logFuncError:(const char *)func msg:(NSString *)fmt, ... {
   1.298 +  va_list args;
   1.299 +  va_start(args, fmt);
   1.300 +  [self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelError];
   1.301 +  va_end(args);
   1.302 +}
   1.303 +
   1.304 +- (void)logFuncAssert:(const char *)func msg:(NSString *)fmt, ... {
   1.305 +  va_list args;
   1.306 +  va_start(args, fmt);
   1.307 +  [self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelAssert];
   1.308 +  va_end(args);
   1.309 +}
   1.310 +
   1.311 +@end  // GTMLoggerMacroHelpers
   1.312 +
   1.313 +@implementation GTMLogger (PrivateMethods)
   1.314 +
   1.315 +- (void)logInternalFunc:(const char *)func
   1.316 +                 format:(NSString *)fmt
   1.317 +                 valist:(va_list)args
   1.318 +                  level:(GTMLoggerLevel)level {
   1.319 +  // Primary point where logging happens, logging should never throw, catch
   1.320 +  // everything.
   1.321 +  @try {
   1.322 +    NSString *fname = func ? [NSString stringWithUTF8String:func] : nil;
   1.323 +    NSString *msg = [formatter_ stringForFunc:fname
   1.324 +                                   withFormat:fmt
   1.325 +                                       valist:args
   1.326 +                                        level:level];
   1.327 +    if (msg && [filter_ filterAllowsMessage:msg level:level])
   1.328 +      [writer_ logMessage:msg level:level];
   1.329 +  }
   1.330 +  @catch (id e) {
   1.331 +    // Ignored
   1.332 +  }
   1.333 +}
   1.334 +
   1.335 +@end  // PrivateMethods
   1.336 +
   1.337 +
   1.338 +@implementation NSFileHandle (GTMFileHandleLogWriter)
   1.339 +
   1.340 ++ (id)fileHandleForLoggingAtPath:(NSString *)path mode:(mode_t)mode {
   1.341 +  int fd = -1;
   1.342 +  if (path) {
   1.343 +    int flags = O_WRONLY | O_APPEND | O_CREAT;
   1.344 +    fd = open([path fileSystemRepresentation], flags, mode);
   1.345 +  }
   1.346 +  if (fd == -1) return nil;
   1.347 +  return [[[self alloc] initWithFileDescriptor:fd
   1.348 +                                closeOnDealloc:YES] autorelease];
   1.349 +}
   1.350 +
   1.351 +- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level {
   1.352 +  @synchronized(self) {
   1.353 +    // Closed pipes should not generate exceptions in our caller. Catch here
   1.354 +    // as well [GTMLogger logInternalFunc:...] so that an exception in this
   1.355 +    // writer does not prevent other writers from having a chance.
   1.356 +    @try {
   1.357 +      NSString *line = [NSString stringWithFormat:@"%@\n", msg];
   1.358 +      [self writeData:[line dataUsingEncoding:NSUTF8StringEncoding]];
   1.359 +    }
   1.360 +    @catch (id e) {
   1.361 +      // Ignored
   1.362 +    }
   1.363 +  }
   1.364 +}
   1.365 +
   1.366 +@end  // GTMFileHandleLogWriter
   1.367 +
   1.368 +
   1.369 +@implementation NSArray (GTMArrayCompositeLogWriter)
   1.370 +
   1.371 +- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level {
   1.372 +  @synchronized(self) {
   1.373 +    id<GTMLogWriter> child = nil;
   1.374 +    GTM_FOREACH_OBJECT(child, self) {
   1.375 +      if ([child conformsToProtocol:@protocol(GTMLogWriter)])
   1.376 +        [child logMessage:msg level:level];
   1.377 +    }
   1.378 +  }
   1.379 +}
   1.380 +
   1.381 +@end  // GTMArrayCompositeLogWriter
   1.382 +
   1.383 +
   1.384 +@implementation GTMLogger (GTMLoggerLogWriter)
   1.385 +
   1.386 +- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level {
   1.387 +  switch (level) {
   1.388 +    case kGTMLoggerLevelDebug:
   1.389 +      [self logDebug:@"%@", msg];
   1.390 +      break;
   1.391 +    case kGTMLoggerLevelInfo:
   1.392 +      [self logInfo:@"%@", msg];
   1.393 +      break;
   1.394 +    case kGTMLoggerLevelError:
   1.395 +      [self logError:@"%@", msg];
   1.396 +      break;
   1.397 +    case kGTMLoggerLevelAssert:
   1.398 +      [self logAssert:@"%@", msg];
   1.399 +      break;
   1.400 +    default:
   1.401 +      // Ignore the message.
   1.402 +      break;
   1.403 +  }
   1.404 +}
   1.405 +
   1.406 +@end  // GTMLoggerLogWriter
   1.407 +
   1.408 +
   1.409 +@implementation GTMLogBasicFormatter
   1.410 +
   1.411 +- (NSString *)prettyNameForFunc:(NSString *)func {
   1.412 +  NSString *name = [func stringByTrimmingCharactersInSet:
   1.413 +                     [NSCharacterSet whitespaceAndNewlineCharacterSet]];
   1.414 +  NSString *function = @"(unknown)";
   1.415 +  if ([name length]) {
   1.416 +    if (// Objective C __func__ and __PRETTY_FUNCTION__
   1.417 +        [name hasPrefix:@"-["] || [name hasPrefix:@"+["] ||
   1.418 +        // C++ __PRETTY_FUNCTION__ and other preadorned formats
   1.419 +        [name hasSuffix:@")"]) {
   1.420 +      function = name;
   1.421 +    } else {
   1.422 +      // Assume C99 __func__
   1.423 +      function = [NSString stringWithFormat:@"%@()", name];
   1.424 +    }
   1.425 +  }
   1.426 +  return function;
   1.427 +}
   1.428 +
   1.429 +- (NSString *)stringForFunc:(NSString *)func
   1.430 +                 withFormat:(NSString *)fmt
   1.431 +                     valist:(va_list)args
   1.432 +                      level:(GTMLoggerLevel)level {
   1.433 +  // Performance note: We may want to do a quick check here to see if |fmt|
   1.434 +  // contains a '%', and if not, simply return 'fmt'.
   1.435 +  if (!(fmt && args)) return nil;
   1.436 +  return [[[NSString alloc] initWithFormat:fmt arguments:args] autorelease];
   1.437 +}
   1.438 +
   1.439 +@end  // GTMLogBasicFormatter
   1.440 +
   1.441 +
   1.442 +@implementation GTMLogStandardFormatter
   1.443 +
   1.444 +- (id)init {
   1.445 +  if ((self = [super init])) {
   1.446 +    dateFormatter_ = [[NSDateFormatter alloc] init];
   1.447 +    [dateFormatter_ setFormatterBehavior:NSDateFormatterBehavior10_4];
   1.448 +    [dateFormatter_ setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSS"];
   1.449 +    pname_ = [[[NSProcessInfo processInfo] processName] copy];
   1.450 +    pid_ = [[NSProcessInfo processInfo] processIdentifier];
   1.451 +    if (!(dateFormatter_ && pname_)) {
   1.452 +      [self release];
   1.453 +      return nil;
   1.454 +    }
   1.455 +  }
   1.456 +  return self;
   1.457 +}
   1.458 +
   1.459 +- (void)dealloc {
   1.460 +  [dateFormatter_ release];
   1.461 +  [pname_ release];
   1.462 +  [super dealloc];
   1.463 +}
   1.464 +
   1.465 +- (NSString *)stringForFunc:(NSString *)func
   1.466 +                 withFormat:(NSString *)fmt
   1.467 +                     valist:(va_list)args
   1.468 +                      level:(GTMLoggerLevel)level {
   1.469 +  NSString *tstamp = nil;
   1.470 +  @synchronized (dateFormatter_) {
   1.471 +    tstamp = [dateFormatter_ stringFromDate:[NSDate date]];
   1.472 +  }
   1.473 +  return [NSString stringWithFormat:@"%@ %@[%d/%p] [lvl=%d] %@ %@",
   1.474 +           tstamp, pname_, pid_, pthread_self(),
   1.475 +           level, [self prettyNameForFunc:func],
   1.476 +           // |super| has guard for nil |fmt| and |args|
   1.477 +           [super stringForFunc:func withFormat:fmt valist:args level:level]];
   1.478 +}
   1.479 +
   1.480 +@end  // GTMLogStandardFormatter
   1.481 +
   1.482 +
   1.483 +@implementation GTMLogLevelFilter
   1.484 +
   1.485 +// Check the environment and the user preferences for the GTMVerboseLogging key
   1.486 +// to see if verbose logging has been enabled. The environment variable will
   1.487 +// override the defaults setting, so check the environment first.
   1.488 +// COV_NF_START
   1.489 +static BOOL IsVerboseLoggingEnabled(void) {
   1.490 +  static NSString *const kVerboseLoggingKey = @"GTMVerboseLogging";
   1.491 +  NSString *value = [[[NSProcessInfo processInfo] environment]
   1.492 +                        objectForKey:kVerboseLoggingKey];
   1.493 +  if (value) {
   1.494 +    // Emulate [NSString boolValue] for pre-10.5
   1.495 +    value = [value stringByTrimmingCharactersInSet:
   1.496 +                [NSCharacterSet whitespaceAndNewlineCharacterSet]];
   1.497 +    if ([[value uppercaseString] hasPrefix:@"Y"] ||
   1.498 +        [[value uppercaseString] hasPrefix:@"T"] ||
   1.499 +        [value intValue]) {
   1.500 +      return YES;
   1.501 +    } else {
   1.502 +      return NO;
   1.503 +    }
   1.504 +  }
   1.505 +  return [[NSUserDefaults standardUserDefaults] boolForKey:kVerboseLoggingKey];
   1.506 +}
   1.507 +// COV_NF_END
   1.508 +
   1.509 +// In DEBUG builds, log everything. If we're not in a debug build we'll assume
   1.510 +// that we're in a Release build.
   1.511 +- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level {
   1.512 +#if DEBUG
   1.513 +  return YES;
   1.514 +#endif
   1.515 +
   1.516 +  BOOL allow = YES;
   1.517 +
   1.518 +  switch (level) {
   1.519 +    case kGTMLoggerLevelDebug:
   1.520 +      allow = NO;
   1.521 +      break;
   1.522 +    case kGTMLoggerLevelInfo:
   1.523 +      allow = IsVerboseLoggingEnabled();
   1.524 +      break;
   1.525 +    case kGTMLoggerLevelError:
   1.526 +      allow = YES;
   1.527 +      break;
   1.528 +    case kGTMLoggerLevelAssert:
   1.529 +      allow = YES;
   1.530 +      break;
   1.531 +    default:
   1.532 +      allow = YES;
   1.533 +      break;
   1.534 +  }
   1.535 +
   1.536 +  return allow;
   1.537 +}
   1.538 +
   1.539 +@end  // GTMLogLevelFilter
   1.540 +
   1.541 +
   1.542 +@implementation GTMLogNoFilter
   1.543 +
   1.544 +- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level {
   1.545 +  return YES;  // Allow everything through
   1.546 +}
   1.547 +
   1.548 +@end  // GTMLogNoFilter
   1.549 +
   1.550 +
   1.551 +@implementation GTMLogAllowedLevelFilter
   1.552 +
   1.553 +// Private designated initializer
   1.554 +- (id)initWithAllowedLevels:(NSIndexSet *)levels {
   1.555 +  self = [super init];
   1.556 +  if (self != nil) {
   1.557 +    allowedLevels_ = [levels retain];
   1.558 +    // Cap min/max level
   1.559 +    if (!allowedLevels_ ||
   1.560 +        // NSIndexSet is unsigned so only check the high bound, but need to
   1.561 +        // check both first and last index because NSIndexSet appears to allow
   1.562 +        // wraparound.
   1.563 +        ([allowedLevels_ firstIndex] > kGTMLoggerLevelAssert) ||
   1.564 +        ([allowedLevels_ lastIndex] > kGTMLoggerLevelAssert)) {
   1.565 +      [self release];
   1.566 +      return nil;
   1.567 +    }
   1.568 +  }
   1.569 +  return self;
   1.570 +}
   1.571 +
   1.572 +- (id)init {
   1.573 +  // Allow all levels in default init
   1.574 +  return [self initWithAllowedLevels:[NSIndexSet indexSetWithIndexesInRange:
   1.575 +             NSMakeRange(kGTMLoggerLevelUnknown,
   1.576 +                 (kGTMLoggerLevelAssert - kGTMLoggerLevelUnknown + 1))]];
   1.577 +}
   1.578 +
   1.579 +- (void)dealloc {
   1.580 +  [allowedLevels_ release];
   1.581 +  [super dealloc];
   1.582 +}
   1.583 +
   1.584 +- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level {
   1.585 +  return [allowedLevels_ containsIndex:level];
   1.586 +}
   1.587 +
   1.588 +@end  // GTMLogAllowedLevelFilter
   1.589 +
   1.590 +
   1.591 +@implementation GTMLogMininumLevelFilter
   1.592 +
   1.593 +- (id)initWithMinimumLevel:(GTMLoggerLevel)level {
   1.594 +  return [super initWithAllowedLevels:[NSIndexSet indexSetWithIndexesInRange:
   1.595 +             NSMakeRange(level,
   1.596 +                         (kGTMLoggerLevelAssert - level + 1))]];
   1.597 +}
   1.598 +
   1.599 +@end  // GTMLogMininumLevelFilter
   1.600 +
   1.601 +
   1.602 +@implementation GTMLogMaximumLevelFilter
   1.603 +
   1.604 +- (id)initWithMaximumLevel:(GTMLoggerLevel)level {
   1.605 +  return [super initWithAllowedLevels:[NSIndexSet indexSetWithIndexesInRange:
   1.606 +             NSMakeRange(kGTMLoggerLevelUnknown, level + 1)]];
   1.607 +}
   1.608 +
   1.609 +@end  // GTMLogMaximumLevelFilter
   1.610 +
   1.611 +#if !defined(__clang__) && (__GNUC__*10+__GNUC_MINOR__ >= 42)
   1.612 +// See comment at top of file.
   1.613 +#pragma GCC diagnostic error "-Wmissing-format-attribute"
   1.614 +#endif  // !__clang__
   1.615 +

mercurial