Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merging latest changes from CocoaLumberjack project

  • Loading branch information...
commit 428baf81dd666b41a1416bf66f0f4140ceacf868 1 parent 3ac9f8f
@robbiehanson authored
View
6 Vendor/CocoaLumberjack/DDAbstractDatabaseLogger.m
@@ -115,6 +115,12 @@ - (void)destroySaveTimer
if (saveTimer)
{
dispatch_source_cancel(saveTimer);
+ if (saveTimerSuspended)
+ {
+ // Must resume a timer before releasing it (or it will crash)
+ dispatch_resume(saveTimer);
+ saveTimerSuspended = NO;
+ }
dispatch_release(saveTimer);
saveTimer = NULL;
}
View
5 Vendor/CocoaLumberjack/DDFileLogger.m
@@ -82,6 +82,11 @@ - (id)initWithLogsDirectory:(NSString *)aLogsDirectory
return self;
}
+- (void)dealloc
+{
+ [self removeObserver:self forKeyPath:@"maximumNumberOfLogFiles"];
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Configuration
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
View
115 Vendor/CocoaLumberjack/DDLog.h
@@ -39,26 +39,33 @@
@protocol DDLogFormatter;
/**
- * Define our big multiline macros so all the other macros will be easy to read.
+ * This is the single macro that all other macros below compile into.
+ * This big multiline macro makes all the other macros easier to read.
**/
-#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, fnct, frmt, ...) \
- [DDLog log:isAsynchronous \
- level:lvl \
- flag:flg \
- context:ctx \
- file:__FILE__ \
- function:fnct \
- line:__LINE__ \
- tag:nil \
+#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
+ [DDLog log:isAsynchronous \
+ level:lvl \
+ flag:flg \
+ context:ctx \
+ file:__FILE__ \
+ function:fnct \
+ line:__LINE__ \
+ tag:atag \
format:(frmt), ##__VA_ARGS__]
+/**
+ * Define the Objective-C and C versions of the macro.
+ * These automatically inject the proper function name for either an objective-c method or c function.
+ *
+ * We also define shorthand versions for asynchronous and synchronous logging.
+**/
#define LOG_OBJC_MACRO(async, lvl, flg, ctx, frmt, ...) \
- LOG_MACRO(async, lvl, flg, ctx, sel_getName(_cmd), frmt, ##__VA_ARGS__)
+ LOG_MACRO(async, lvl, flg, ctx, nil, sel_getName(_cmd), frmt, ##__VA_ARGS__)
#define LOG_C_MACRO(async, lvl, flg, ctx, frmt, ...) \
- LOG_MACRO(async, lvl, flg, ctx, __FUNCTION__, frmt, ##__VA_ARGS__)
+ LOG_MACRO(async, lvl, flg, ctx, nil, __FUNCTION__, frmt, ##__VA_ARGS__)
#define SYNC_LOG_OBJC_MACRO(lvl, flg, ctx, frmt, ...) \
LOG_OBJC_MACRO( NO, lvl, flg, ctx, frmt, ##__VA_ARGS__)
@@ -72,9 +79,26 @@
#define ASYNC_LOG_C_MACRO(lvl, flg, ctx, frmt, ...) \
LOG_C_MACRO(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
+/**
+ * Define version of the macro that only execute if the logLevel is above the threshold.
+ * The compiled versions essentially look like this:
+ *
+ * if (logFlagForThisLogMsg & ddLogLevel) { execute log message }
+ *
+ * As shown further below, Lumberjack actually uses a bitmask as opposed to primitive log levels.
+ * This allows for a great amount of flexibility and some pretty advanced fine grained logging techniques.
+ *
+ * Note that when compiler optimizations are enabled (as they are for your release builds),
+ * the log messages above your logging threshold will automatically be compiled out.
+ *
+ * (If the compiler sees ddLogLevel declared as a constant, the compiler simply checks to see if the 'if' statement
+ * would execute, and if not it strips it from the binary.)
+ *
+ * We also define shorthand versions for asynchronous and synchronous logging.
+**/
#define LOG_MAYBE(async, lvl, flg, ctx, fnct, frmt, ...) \
- do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, fnct, frmt, ##__VA_ARGS__); } while(0)
+ do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, nil, fnct, frmt, ##__VA_ARGS__); } while(0)
#define LOG_OBJC_MAYBE(async, lvl, flg, ctx, frmt, ...) \
LOG_MAYBE(async, lvl, flg, ctx, sel_getName(_cmd), frmt, ##__VA_ARGS__)
@@ -95,6 +119,31 @@
LOG_C_MAYBE(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
/**
+ * Define versions of the macros that also accept tags.
+ *
+ * The DDLogMessage object includes a 'tag' ivar that may be used for a variety of purposes.
+ * It may be used to pass custom information to loggers or formatters.
+ * Or it may be used by 3rd party extensions to the framework.
+ *
+ * Thes macros just make it a little easier to extend logging functionality.
+**/
+
+#define LOG_OBJC_TAG_MACRO(async, lvl, flg, ctx, tag, frmt, ...) \
+ LOG_MACRO(async, lvl, flg, ctx, tag, sel_getName(_cmd), frmt, ##__VA_ARGS__)
+
+#define LOG_C_TAG_MACRO(async, lvl, flg, ctx, tag, frmt, ...) \
+ LOG_MACRO(async, lvl, flg, ctx, tag, __FUNCTION__, frmt, ##__VA_ARGS__)
+
+#define LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, ...) \
+ do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
+
+#define LOG_OBJC_TAG_MAYBE(async, lvl, flg, ctx, tag, frmt, ...) \
+ LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, sel_getName(_cmd), frmt, ##__VA_ARGS__)
+
+#define LOG_C_TAG_MAYBE(async, lvl, flg, ctx, tag, frmt, ...) \
+ LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, __FUNCTION__, frmt, ##__VA_ARGS__)
+
+/**
* Define the standard options.
*
* We default to only 4 levels because it makes it easier for beginners
@@ -246,7 +295,8 @@ NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
* Logging Primitive.
*
* This method can be used if you have a prepared va_list.
- */
+**/
+
+ (void)log:(BOOL)asynchronous
level:(int)level
flag:(int)flag
@@ -307,8 +357,9 @@ NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
/**
* Formatters may optionally be added to any logger.
- * If no formatter is set, the logger simply logs the message as it is given in logMessage.
- * Or it may use its own built in formatting style.
+ *
+ * If no formatter is set, the logger simply logs the message as it is given in logMessage,
+ * or it may use its own built in formatting style.
**/
- (id <DDLogFormatter>)logFormatter;
- (void)setLogFormatter:(id <DDLogFormatter>)formatter;
@@ -423,6 +474,12 @@ NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
* If you write custom loggers or formatters, you will be dealing with objects of this class.
**/
+enum {
+ DDLogMessageCopyFile = 1 << 0,
+ DDLogMessageCopyFunction = 1 << 1,
+};
+typedef int DDLogMessageOptions;
+
@interface DDLogMessage : NSObject
{
@@ -435,23 +492,34 @@ NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
int logContext;
NSString *logMsg;
NSDate *timestamp;
- const char *file;
- const char *function;
+ char *file;
+ char *function;
int lineNumber;
mach_port_t machThreadID;
char *queueLabel;
NSString *threadName;
- id tag; // For 3rd party extensions to the framework, where flags and contexts aren't enough.
+
+ // For 3rd party extensions to the framework, where flags and contexts aren't enough.
+ id tag;
+
+ // For 3rd party extensions that manually create DDLogMessage instances.
+ DDLogMessageOptions options;
}
/**
- * The initializer is somewhat reserved for internal use.
- * However, if you find need to manually create logMessage objects, there is one thing you should be aware of:
+ * Standard init method for a log message object.
+ * Used by the logging primitives. (And the macros use the logging primitives.)
+ *
+ * If you find need to manually create logMessage objects, there is one thing you should be aware of:
*
- * The initializer expects the file and function parameters to be string literals.
+ * If no flags are passed, the method expects the file and function parameters to be string literals.
* That is, it expects the given strings to exist for the duration of the object's lifetime,
* and it expects the given strings to be immutable.
* In other words, it does not copy these strings, it simply points to them.
+ * This is due to the fact that __FILE__ and __FUNCTION__ are usually used to specify these parameters,
+ * so it makes sense to optimize and skip the unnecessary allocations.
+ * However, if you need them to be copied you may use the options parameter to specify this.
+ * Options is a bitmask which supports DDLogMessageCopyFile and DDLogMessageCopyFunction.
**/
- (id)initWithLogMsg:(NSString *)logMsg
level:(int)logLevel
@@ -460,7 +528,8 @@ NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
file:(const char *)file
function:(const char *)function
line:(int)line
- tag:(id)tag;
+ tag:(id)tag
+ options:(DDLogMessageOptions)optionsMask;
/**
* Returns the threadID as it appears in NSLog.
View
50 Vendor/CocoaLumberjack/DDLog.m
@@ -278,7 +278,8 @@ + (void)log:(BOOL)asynchronous
file:file
function:function
line:line
- tag:tag];
+ tag:tag
+ options:0];
[self queueLogMessage:logMessage asynchronously:asynchronous];
@@ -307,7 +308,8 @@ + (void)log:(BOOL)asynchronous
file:file
function:function
line:line
- tag:tag];
+ tag:tag
+ options:0];
[self queueLogMessage:logMessage asynchronously:asynchronous];
}
@@ -793,6 +795,18 @@ - (void)dealloc
@implementation DDLogMessage
+static char *dd_str_copy(const char *str)
+{
+ if (str == NULL) return NULL;
+
+ size_t length = strlen(str);
+ char * result = malloc(length + 1);
+ strncpy(result, str, length);
+ result[length] = 0;
+
+ return result;
+}
+
- (id)initWithLogMsg:(NSString *)msg
level:(int)level
flag:(int)flag
@@ -801,6 +815,7 @@ - (id)initWithLogMsg:(NSString *)msg
function:(const char *)aFunction
line:(int)line
tag:(id)aTag
+ options:(DDLogMessageOptions)optionsMask
{
if ((self = [super init]))
{
@@ -808,23 +823,25 @@ - (id)initWithLogMsg:(NSString *)msg
logLevel = level;
logFlag = flag;
logContext = context;
- file = aFile;
- function = aFunction;
lineNumber = line;
tag = aTag;
+ options = optionsMask;
+
+ if (options & DDLogMessageCopyFile)
+ file = dd_str_copy(aFile);
+ else
+ file = (char *)aFile;
+
+ if (options & DDLogMessageCopyFunction)
+ file = dd_str_copy(aFunction);
+ else
+ function = (char *)aFunction;
timestamp = [[NSDate alloc] init];
machThreadID = pthread_mach_thread_np(pthread_self());
- const char *label = dispatch_queue_get_label(dispatch_get_current_queue());
- if (label)
- {
- size_t labelLength = strlen(label);
- queueLabel = malloc(labelLength+1);
- strncpy(queueLabel, label, labelLength);
- queueLabel[labelLength] = 0;
- }
+ queueLabel = dd_str_copy(dispatch_queue_get_label(dispatch_get_current_queue()));
threadName = [[NSThread currentThread] name];
}
@@ -851,9 +868,14 @@ - (NSString *)methodName
- (void)dealloc
{
- if (queueLabel != NULL) {
+ if (file && (options & DDLogMessageCopyFile))
+ free(file);
+
+ if (function && (options & DDLogMessageCopyFunction))
+ free(function);
+
+ if (queueLabel)
free(queueLabel);
- }
}
@end
View
81 Vendor/CocoaLumberjack/DDTTYLogger.h
@@ -1,5 +1,9 @@
#import <Foundation/Foundation.h>
+#if !TARGET_OS_IPHONE
+#import <AppKit/NSColor.h>
+#endif
+
#import "DDLog.h"
/**
@@ -40,11 +44,29 @@
size_t pidLen;
BOOL colorsEnabled;
- NSMutableArray *colorProfiles;
+ NSMutableArray *colorProfilesArray;
+ NSMutableDictionary *colorProfilesDict;
}
+ (DDTTYLogger *)sharedInstance;
+/* Inherited from the DDLogger protocol:
+ *
+ * Formatters may optionally be added to any logger.
+ *
+ * If no formatter is set, the logger simply logs the message as it is given in logMessage,
+ * or it may use its own built in formatting style.
+ *
+ * More information about formatters can be found here:
+ * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters
+ *
+ * The actual implementation of these methods is inherited from DDAbstractLogger.
+
+- (id <DDLogFormatter>)logFormatter;
+- (void)setLogFormatter:(id <DDLogFormatter>)formatter;
+
+*/
+
/**
* Want to use different colors for different log levels?
* Enable this property.
@@ -67,9 +89,7 @@
* - LOG_FLAG_WARN = (orange, nil)
*
* You can customize the colors however you see fit.
- * There are a few things you may need to be aware of:
- *
- * You are passing a flag, NOT a level.
+ * Please note that you are passing a flag, NOT a level.
*
* GOOD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:LOG_FLAG_INFO]; // <- Good :)
* BAD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:LOG_LEVEL_INFO]; // <- BAD! :(
@@ -79,10 +99,10 @@
*
* If you run the application within Xcode, then the XcodeColors plugin is required.
*
- * If you run the application from a shell, then DDTTYLogger will automatically try to map the given color to
+ * If you run the application from a shell, then DDTTYLogger will automatically map the given color to
* the closest available color. (xterm-256color or xterm-color which have 256 and 16 supported colors respectively.)
*
- * This method invokes setForegroundColor:backgroundColor:forFlag:context:, and passes the default context (0).
+ * This method invokes setForegroundColor:backgroundColor:forFlag:context: and passes the default context (0).
**/
#if TARGET_OS_IPHONE
- (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forFlag:(int)mask;
@@ -91,9 +111,11 @@
#endif
/**
- * Allows you to customize the color for a particular flag, within a particular logging context.
+ * Just like setForegroundColor:backgroundColor:flag, but allows you to specify a particular logging context.
+ *
+ * A logging context is often used to identify log messages coming from a 3rd party framework,
+ * although logging context's can be used for many different functions.
*
- * A logging context may identify log messages coming from a 3rd party framework.
* Logging context's are explained in further detail here:
* https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomContext
**/
@@ -104,26 +126,41 @@
#endif
/**
- * Clears the color profiles for a particular flag.
+ * Similar to the methods above, but allows you to map DDLogMessage->tag to a particular color profile.
+ * For example, you could do something like this:
+ *
+ * static NSString *const PurpleTag = @"PurpleTag";
+ *
+ * #define DDLogPurple(frmt, ...) LOG_OBJC_TAG_MACRO(NO, 0, 0, 0, PurpleTag, frmt, ##__VA_ARGS__)
+ *
+ * And then in your applicationDidFinishLaunching, or wherever you configure Lumberjack:
+ *
+ * #if TARGET_OS_IPHONE
+ * UIColor *purple = [UIColor colorWithRed:(64/255.0) green:(0/255.0) blue:(128/255.0) alpha:1.0];
+ * #else
+ * NSColor *purple = [NSColor colorWithCalibratedRed:(64/255.0) green:(0/255.0) blue:(128/255.0) alpha:1.0];
*
- * This method invokes clearColorsForFlag:context:, and passes the default context (0).
+ * [[DDTTYLogger sharedInstance] setForegroundColor:purple backgroundColor:nil forTag:PurpleTag];
+ * [DDLog addLogger:[DDTTYLogger sharedInstance]];
+ *
+ * This would essentially give you a straight NSLog replacement that prints in purple:
+ *
+ * DDLogPurple(@"I'm a purple log message!");
**/
-- (void)clearColorsForFlag:(int)mask;
+#if TARGET_OS_IPHONE
+- (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forTag:(id <NSCopying>)tag;
+#else
+- (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forTag:(id <NSCopying>)tag;
+#endif
/**
- * Clears the color profiles for a particular flag, within a particular logging context.
+ * Clearing color profiles.
**/
+- (void)clearColorsForFlag:(int)mask;
- (void)clearColorsForFlag:(int)mask context:(int)context;
-
-/**
- * Clears all color profiles.
-**/
+- (void)clearColorsForTag:(id <NSCopying>)tag;
- (void)clearColorsForAllFlags;
-
-
-// Inherited from DDAbstractLogger
-
-// - (id <DDLogFormatter>)logFormatter;
-// - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
+- (void)clearColorsForAllTags;
+- (void)clearAllColors;
@end
View
181 Vendor/CocoaLumberjack/DDTTYLogger.m
@@ -55,14 +55,7 @@
// To reset the foreground and background color (to default values) in one operation:
// Insert the ESCAPE_SEQ into your string, followed by ";"
-#define XCODE_COLORS_ESCAPE_SEQ_MAC "\033["
-#define XCODE_COLORS_ESCAPE_SEQ_IOS "\xC2\xA0["
-
-#if TARGET_OS_IPHONE
- #define XCODE_COLORS_ESCAPE_SEQ XCODE_COLORS_ESCAPE_SEQ_IOS
-#else
- #define XCODE_COLORS_ESCAPE_SEQ XCODE_COLORS_ESCAPE_SEQ_MAC
-#endif
+#define XCODE_COLORS_ESCAPE_SEQ "\033["
#define XCODE_COLORS_RESET_FG XCODE_COLORS_ESCAPE_SEQ "fg;" // Clear any foreground color
#define XCODE_COLORS_RESET_BG XCODE_COLORS_ESCAPE_SEQ "bg;" // Clear any background color
@@ -122,7 +115,6 @@ @interface DDTTYLoggerColorProfile : NSObject {
size_t resetCodeLen;
}
-- (id)initWithForegroundColor:(OSColor *)fgColor backgroundColor:(OSColor *)bgColor flag:(int)mask;
- (id)initWithForegroundColor:(OSColor *)fgColor backgroundColor:(OSColor *)bgColor flag:(int)mask context:(int)ctxt;
@end
@@ -863,7 +855,8 @@ - (id)init
// Initialize color stuff
colorsEnabled = NO;
- colorProfiles = [[NSMutableArray alloc] init];
+ colorProfilesArray = [[NSMutableArray alloc] initWithCapacity:8];
+ colorProfilesDict = [[NSMutableDictionary alloc] initWithCapacity:8];
}
}
return self;
@@ -908,7 +901,7 @@ - (void)setColorsEnabled:(BOOL)newColorsEnabled
colorsEnabled = newColorsEnabled;
- if ([colorProfiles count] == 0) {
+ if ([colorProfilesArray count] == 0) {
[self loadDefaultColorProfiles];
}
}};
@@ -950,7 +943,7 @@ - (void)setForegroundColor:(OSColor *)txtColor backgroundColor:(OSColor *)bgColo
NSLogInfo(@"DDTTYLogger: newColorProfile: %@", newColorProfile);
NSUInteger i = 0;
- for (DDTTYLoggerColorProfile *colorProfile in colorProfiles)
+ for (DDTTYLoggerColorProfile *colorProfile in colorProfilesArray)
{
if ((colorProfile->mask == mask) && (colorProfile->context == ctxt))
{
@@ -960,10 +953,46 @@ - (void)setForegroundColor:(OSColor *)txtColor backgroundColor:(OSColor *)bgColo
i++;
}
- if (i < [colorProfiles count])
- [colorProfiles replaceObjectAtIndex:i withObject:newColorProfile];
+ if (i < [colorProfilesArray count])
+ [colorProfilesArray replaceObjectAtIndex:i withObject:newColorProfile];
else
- [colorProfiles addObject:newColorProfile];
+ [colorProfilesArray addObject:newColorProfile];
+ }};
+
+ // The design of the setter logic below is taken from the DDAbstractLogger implementation.
+ // For documentation please refer to the DDAbstractLogger implementation.
+
+ dispatch_queue_t currentQueue = dispatch_get_current_queue();
+ if (currentQueue == loggerQueue)
+ {
+ block();
+ }
+ else
+ {
+ dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
+ NSAssert(currentQueue != globalLoggingQueue, @"Core architecture requirement failure");
+
+ dispatch_async(globalLoggingQueue, ^{
+ dispatch_async(loggerQueue, block);
+ });
+ }
+}
+
+- (void)setForegroundColor:(OSColor *)txtColor backgroundColor:(OSColor *)bgColor forTag:(id <NSCopying>)tag
+{
+ NSAssert([(id <NSObject>)tag conformsToProtocol:@protocol(NSCopying)], @"Invalid tag");
+
+ dispatch_block_t block = ^{ @autoreleasepool {
+
+ DDTTYLoggerColorProfile *newColorProfile =
+ [[DDTTYLoggerColorProfile alloc] initWithForegroundColor:txtColor
+ backgroundColor:bgColor
+ flag:0
+ context:0];
+
+ NSLogInfo(@"DDTTYLogger: newColorProfile: %@", newColorProfile);
+
+ [colorProfilesDict setObject:newColorProfile forKey:tag];
}};
// The design of the setter logic below is taken from the DDAbstractLogger implementation.
@@ -995,7 +1024,7 @@ - (void)clearColorsForFlag:(int)mask context:(int)context
dispatch_block_t block = ^{ @autoreleasepool {
NSUInteger i = 0;
- for (DDTTYLoggerColorProfile *colorProfile in colorProfiles)
+ for (DDTTYLoggerColorProfile *colorProfile in colorProfilesArray)
{
if ((colorProfile->mask == mask) && (colorProfile->context == context))
{
@@ -1005,9 +1034,9 @@ - (void)clearColorsForFlag:(int)mask context:(int)context
i++;
}
- if (i < [colorProfiles count])
+ if (i < [colorProfilesArray count])
{
- [colorProfiles removeObjectAtIndex:i];
+ [colorProfilesArray removeObjectAtIndex:i];
}
}};
@@ -1030,11 +1059,92 @@ - (void)clearColorsForFlag:(int)mask context:(int)context
}
}
+- (void)clearColorsForTag:(id <NSCopying>)tag
+{
+ NSAssert([(id <NSObject>)tag conformsToProtocol:@protocol(NSCopying)], @"Invalid tag");
+
+ dispatch_block_t block = ^{ @autoreleasepool {
+
+ [colorProfilesDict removeObjectForKey:tag];
+ }};
+
+ // The design of the setter logic below is taken from the DDAbstractLogger implementation.
+ // For documentation please refer to the DDAbstractLogger implementation.
+
+ dispatch_queue_t currentQueue = dispatch_get_current_queue();
+ if (currentQueue == loggerQueue)
+ {
+ block();
+ }
+ else
+ {
+ dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
+ NSAssert(currentQueue != globalLoggingQueue, @"Core architecture requirement failure");
+
+ dispatch_async(globalLoggingQueue, ^{
+ dispatch_async(loggerQueue, block);
+ });
+ }
+}
+
- (void)clearColorsForAllFlags
{
dispatch_block_t block = ^{ @autoreleasepool {
- [colorProfiles removeAllObjects];
+ [colorProfilesArray removeAllObjects];
+ }};
+
+ // The design of the setter logic below is taken from the DDAbstractLogger implementation.
+ // For documentation please refer to the DDAbstractLogger implementation.
+
+ dispatch_queue_t currentQueue = dispatch_get_current_queue();
+ if (currentQueue == loggerQueue)
+ {
+ block();
+ }
+ else
+ {
+ dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
+ NSAssert(currentQueue != globalLoggingQueue, @"Core architecture requirement failure");
+
+ dispatch_async(globalLoggingQueue, ^{
+ dispatch_async(loggerQueue, block);
+ });
+ }
+}
+
+- (void)clearColorsForAllTags
+{
+ dispatch_block_t block = ^{ @autoreleasepool {
+
+ [colorProfilesDict removeAllObjects];
+ }};
+
+ // The design of the setter logic below is taken from the DDAbstractLogger implementation.
+ // For documentation please refer to the DDAbstractLogger implementation.
+
+ dispatch_queue_t currentQueue = dispatch_get_current_queue();
+ if (currentQueue == loggerQueue)
+ {
+ block();
+ }
+ else
+ {
+ dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
+ NSAssert(currentQueue != globalLoggingQueue, @"Core architecture requirement failure");
+
+ dispatch_async(globalLoggingQueue, ^{
+ dispatch_async(loggerQueue, block);
+ });
+ }
+}
+
+- (void)clearAllColors
+{
+ dispatch_block_t block = ^{ @autoreleasepool {
+
+ [colorProfilesArray removeAllObjects];
+ [colorProfilesDict removeAllObjects];
}};
// The design of the setter logic below is taken from the DDAbstractLogger implementation.
@@ -1077,21 +1187,33 @@ - (void)logMessage:(DDLogMessage *)logMessage
if (colorsEnabled)
{
- for (DDTTYLoggerColorProfile *cp in colorProfiles)
+ if (logMessage->tag)
+ {
+ colorProfile = [colorProfilesDict objectForKey:logMessage->tag];
+ }
+ if (colorProfile == nil)
{
- if ((logMessage->logFlag & cp->mask) && (logMessage->logContext == cp->context))
+ for (DDTTYLoggerColorProfile *cp in colorProfilesArray)
{
- colorProfile = cp;
- break;
+ if ((logMessage->logFlag & cp->mask) && (logMessage->logContext == cp->context))
+ {
+ colorProfile = cp;
+ break;
+ }
}
}
}
// Convert log message to C string.
- // The technique below is faster than using the UTF8String method.
+ //
+ // We use the stack instead of the heap for speed if possible.
+ // But we're extra cautious to avoid a stack overflow.
NSUInteger msgLen = [logMsg lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
- char msg[msgLen + 1];
+ const BOOL useStack = msgLen < (1024 * 4);
+
+ char msgStack[useStack ? (msgLen + 1) : 0];
+ char *msg = useStack ? msgStack : (char *)malloc(msgLen + 1);
[logMsg getCString:msg maxLength:(msgLen + 1) encoding:NSUTF8StringEncoding];
@@ -1219,6 +1341,10 @@ - (void)logMessage:(DDLogMessage *)logMessage
writev(STDERR_FILENO, v, 12);
}
+
+ if (!useStack) {
+ free(msg);
+ }
}
}
@@ -1233,11 +1359,6 @@ - (NSString *)loggerName
@implementation DDTTYLoggerColorProfile
-- (id)initWithForegroundColor:(OSColor *)fgColor backgroundColor:(OSColor *)bgColor flag:(int)aMask
-{
- return [self initWithForegroundColor:fgColor backgroundColor:bgColor flag:aMask context:0];
-}
-
- (id)initWithForegroundColor:(OSColor *)fgColor backgroundColor:(OSColor *)bgColor flag:(int)aMask context:(int)ctxt
{
if ((self = [super init]))
Please sign in to comment.
Something went wrong with that request. Please try again.