Skip to content

Commit c73ab6b

Browse files
committed
Merging latest changes from CocoaLumberjack project
1 parent 899d99b commit c73ab6b

File tree

6 files changed

+445
-96
lines changed

6 files changed

+445
-96
lines changed

Vendor/CocoaLumberjack/DDAbstractDatabaseLogger.m

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,32 @@
1515
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
1616
#endif
1717

18+
/**
19+
* Does ARC support support GCD objects?
20+
* It does if the minimum deployment target is iOS 6+ or Mac OS X 8+
21+
**/
22+
#if TARGET_OS_IPHONE
23+
24+
// Compiling for iOS
25+
26+
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000 // iOS 6.0 or later
27+
#define NEEDS_DISPATCH_RETAIN_RELEASE 0
28+
#else // iOS 5.X or earlier
29+
#define NEEDS_DISPATCH_RETAIN_RELEASE 1
30+
#endif
31+
32+
#else
33+
34+
// Compiling for Mac OS X
35+
36+
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 // Mac OS X 10.8 or later
37+
#define NEEDS_DISPATCH_RETAIN_RELEASE 0
38+
#else
39+
#define NEEDS_DISPATCH_RETAIN_RELEASE 1 // Mac OS X 10.7 or earlier
40+
#endif
41+
42+
#endif
43+
1844
@interface DDAbstractDatabaseLogger ()
1945
- (void)destroySaveTimer;
2046
- (void)destroyDeleteTimer;
@@ -115,7 +141,15 @@ - (void)destroySaveTimer
115141
if (saveTimer)
116142
{
117143
dispatch_source_cancel(saveTimer);
144+
if (saveTimerSuspended)
145+
{
146+
// Must resume a timer before releasing it (or it will crash)
147+
dispatch_resume(saveTimer);
148+
saveTimerSuspended = NO;
149+
}
150+
#if NEEDS_DISPATCH_RETAIN_RELEASE
118151
dispatch_release(saveTimer);
152+
#endif
119153
saveTimer = NULL;
120154
}
121155
}
@@ -158,7 +192,9 @@ - (void)destroyDeleteTimer
158192
if (deleteTimer)
159193
{
160194
dispatch_source_cancel(deleteTimer);
195+
#if NEEDS_DISPATCH_RETAIN_RELEASE
161196
dispatch_release(deleteTimer);
197+
#endif
162198
deleteTimer = NULL;
163199
}
164200
}

Vendor/CocoaLumberjack/DDFileLogger.m

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,31 @@
1919
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
2020
#endif
2121

22+
// Does ARC support support GCD objects?
23+
// It does if the minimum deployment target is iOS 6+ or Mac OS X 8+
24+
25+
#if TARGET_OS_IPHONE
26+
27+
// Compiling for iOS
28+
29+
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000 // iOS 6.0 or later
30+
#define NEEDS_DISPATCH_RETAIN_RELEASE 0
31+
#else // iOS 5.X or earlier
32+
#define NEEDS_DISPATCH_RETAIN_RELEASE 1
33+
#endif
34+
35+
#else
36+
37+
// Compiling for Mac OS X
38+
39+
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 // Mac OS X 10.8 or later
40+
#define NEEDS_DISPATCH_RETAIN_RELEASE 0
41+
#else
42+
#define NEEDS_DISPATCH_RETAIN_RELEASE 1 // Mac OS X 10.7 or earlier
43+
#endif
44+
45+
#endif
46+
2247
// We probably shouldn't be using DDLog() statements within the DDLog implementation.
2348
// But we still want to leave our log statements for any future debugging,
2449
// and to allow other developers to trace the implementation (which is a great learning tool).
@@ -82,6 +107,11 @@ - (id)initWithLogsDirectory:(NSString *)aLogsDirectory
82107
return self;
83108
}
84109

110+
- (void)dealloc
111+
{
112+
[self removeObserver:self forKeyPath:@"maximumNumberOfLogFiles"];
113+
}
114+
85115
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
86116
#pragma mark Configuration
87117
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -480,7 +510,6 @@ - (void)dealloc
480510
if (rollingTimer)
481511
{
482512
dispatch_source_cancel(rollingTimer);
483-
dispatch_release(rollingTimer);
484513
rollingTimer = NULL;
485514
}
486515
}
@@ -616,7 +645,6 @@ - (void)scheduleTimerToRollLogFileDueToAge
616645
if (rollingTimer)
617646
{
618647
dispatch_source_cancel(rollingTimer);
619-
dispatch_release(rollingTimer);
620648
rollingTimer = NULL;
621649
}
622650

@@ -645,6 +673,13 @@ - (void)scheduleTimerToRollLogFileDueToAge
645673

646674
}});
647675

676+
#if NEEDS_DISPATCH_RETAIN_RELEASE
677+
dispatch_source_t theRollingTimer = rollingTimer;
678+
dispatch_source_set_cancel_handler(rollingTimer, ^{
679+
dispatch_release(theRollingTimer);
680+
});
681+
#endif
682+
648683
uint64_t delay = [logFileRollingDate timeIntervalSinceNow] * NSEC_PER_SEC;
649684
dispatch_time_t fireTime = dispatch_time(DISPATCH_TIME_NOW, delay);
650685

@@ -704,7 +739,6 @@ - (void)rollLogFileNow
704739
if (rollingTimer)
705740
{
706741
dispatch_source_cancel(rollingTimer);
707-
dispatch_release(rollingTimer);
708742
rollingTimer = NULL;
709743
}
710744
}

Vendor/CocoaLumberjack/DDLog.h

Lines changed: 92 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,33 @@
3939
@protocol DDLogFormatter;
4040

4141
/**
42-
* Define our big multiline macros so all the other macros will be easy to read.
42+
* This is the single macro that all other macros below compile into.
43+
* This big multiline macro makes all the other macros easier to read.
4344
**/
4445

45-
#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, fnct, frmt, ...) \
46-
[DDLog log:isAsynchronous \
47-
level:lvl \
48-
flag:flg \
49-
context:ctx \
50-
file:__FILE__ \
51-
function:fnct \
52-
line:__LINE__ \
53-
tag:nil \
46+
#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
47+
[DDLog log:isAsynchronous \
48+
level:lvl \
49+
flag:flg \
50+
context:ctx \
51+
file:__FILE__ \
52+
function:fnct \
53+
line:__LINE__ \
54+
tag:atag \
5455
format:(frmt), ##__VA_ARGS__]
5556

57+
/**
58+
* Define the Objective-C and C versions of the macro.
59+
* These automatically inject the proper function name for either an objective-c method or c function.
60+
*
61+
* We also define shorthand versions for asynchronous and synchronous logging.
62+
**/
5663

5764
#define LOG_OBJC_MACRO(async, lvl, flg, ctx, frmt, ...) \
58-
LOG_MACRO(async, lvl, flg, ctx, sel_getName(_cmd), frmt, ##__VA_ARGS__)
65+
LOG_MACRO(async, lvl, flg, ctx, nil, sel_getName(_cmd), frmt, ##__VA_ARGS__)
5966

6067
#define LOG_C_MACRO(async, lvl, flg, ctx, frmt, ...) \
61-
LOG_MACRO(async, lvl, flg, ctx, __FUNCTION__, frmt, ##__VA_ARGS__)
68+
LOG_MACRO(async, lvl, flg, ctx, nil, __FUNCTION__, frmt, ##__VA_ARGS__)
6269

6370
#define SYNC_LOG_OBJC_MACRO(lvl, flg, ctx, frmt, ...) \
6471
LOG_OBJC_MACRO( NO, lvl, flg, ctx, frmt, ##__VA_ARGS__)
@@ -72,9 +79,26 @@
7279
#define ASYNC_LOG_C_MACRO(lvl, flg, ctx, frmt, ...) \
7380
LOG_C_MACRO(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
7481

82+
/**
83+
* Define version of the macro that only execute if the logLevel is above the threshold.
84+
* The compiled versions essentially look like this:
85+
*
86+
* if (logFlagForThisLogMsg & ddLogLevel) { execute log message }
87+
*
88+
* As shown further below, Lumberjack actually uses a bitmask as opposed to primitive log levels.
89+
* This allows for a great amount of flexibility and some pretty advanced fine grained logging techniques.
90+
*
91+
* Note that when compiler optimizations are enabled (as they are for your release builds),
92+
* the log messages above your logging threshold will automatically be compiled out.
93+
*
94+
* (If the compiler sees ddLogLevel declared as a constant, the compiler simply checks to see if the 'if' statement
95+
* would execute, and if not it strips it from the binary.)
96+
*
97+
* We also define shorthand versions for asynchronous and synchronous logging.
98+
**/
7599

76100
#define LOG_MAYBE(async, lvl, flg, ctx, fnct, frmt, ...) \
77-
do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, fnct, frmt, ##__VA_ARGS__); } while(0)
101+
do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, nil, fnct, frmt, ##__VA_ARGS__); } while(0)
78102

79103
#define LOG_OBJC_MAYBE(async, lvl, flg, ctx, frmt, ...) \
80104
LOG_MAYBE(async, lvl, flg, ctx, sel_getName(_cmd), frmt, ##__VA_ARGS__)
@@ -94,6 +118,31 @@
94118
#define ASYNC_LOG_C_MAYBE(lvl, flg, ctx, frmt, ...) \
95119
LOG_C_MAYBE(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
96120

121+
/**
122+
* Define versions of the macros that also accept tags.
123+
*
124+
* The DDLogMessage object includes a 'tag' ivar that may be used for a variety of purposes.
125+
* It may be used to pass custom information to loggers or formatters.
126+
* Or it may be used by 3rd party extensions to the framework.
127+
*
128+
* Thes macros just make it a little easier to extend logging functionality.
129+
**/
130+
131+
#define LOG_OBJC_TAG_MACRO(async, lvl, flg, ctx, tag, frmt, ...) \
132+
LOG_MACRO(async, lvl, flg, ctx, tag, sel_getName(_cmd), frmt, ##__VA_ARGS__)
133+
134+
#define LOG_C_TAG_MACRO(async, lvl, flg, ctx, tag, frmt, ...) \
135+
LOG_MACRO(async, lvl, flg, ctx, tag, __FUNCTION__, frmt, ##__VA_ARGS__)
136+
137+
#define LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, ...) \
138+
do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
139+
140+
#define LOG_OBJC_TAG_MAYBE(async, lvl, flg, ctx, tag, frmt, ...) \
141+
LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, sel_getName(_cmd), frmt, ##__VA_ARGS__)
142+
143+
#define LOG_C_TAG_MAYBE(async, lvl, flg, ctx, tag, frmt, ...) \
144+
LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, __FUNCTION__, frmt, ##__VA_ARGS__)
145+
97146
/**
98147
* Define the standard options.
99148
*
@@ -246,7 +295,8 @@ NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
246295
* Logging Primitive.
247296
*
248297
* This method can be used if you have a prepared va_list.
249-
*/
298+
**/
299+
250300
+ (void)log:(BOOL)asynchronous
251301
level:(int)level
252302
flag:(int)flag
@@ -307,8 +357,9 @@ NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
307357

308358
/**
309359
* Formatters may optionally be added to any logger.
310-
* If no formatter is set, the logger simply logs the message as it is given in logMessage.
311-
* Or it may use its own built in formatting style.
360+
*
361+
* If no formatter is set, the logger simply logs the message as it is given in logMessage,
362+
* or it may use its own built in formatting style.
312363
**/
313364
- (id <DDLogFormatter>)logFormatter;
314365
- (void)setLogFormatter:(id <DDLogFormatter>)formatter;
@@ -423,6 +474,12 @@ NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
423474
* If you write custom loggers or formatters, you will be dealing with objects of this class.
424475
**/
425476

477+
enum {
478+
DDLogMessageCopyFile = 1 << 0,
479+
DDLogMessageCopyFunction = 1 << 1,
480+
};
481+
typedef int DDLogMessageOptions;
482+
426483
@interface DDLogMessage : NSObject
427484
{
428485

@@ -435,23 +492,34 @@ NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
435492
int logContext;
436493
NSString *logMsg;
437494
NSDate *timestamp;
438-
const char *file;
439-
const char *function;
495+
char *file;
496+
char *function;
440497
int lineNumber;
441498
mach_port_t machThreadID;
442499
char *queueLabel;
443500
NSString *threadName;
444-
id tag; // For 3rd party extensions to the framework, where flags and contexts aren't enough.
501+
502+
// For 3rd party extensions to the framework, where flags and contexts aren't enough.
503+
id tag;
504+
505+
// For 3rd party extensions that manually create DDLogMessage instances.
506+
DDLogMessageOptions options;
445507
}
446508

447509
/**
448-
* The initializer is somewhat reserved for internal use.
449-
* However, if you find need to manually create logMessage objects, there is one thing you should be aware of:
510+
* Standard init method for a log message object.
511+
* Used by the logging primitives. (And the macros use the logging primitives.)
512+
*
513+
* If you find need to manually create logMessage objects, there is one thing you should be aware of:
450514
*
451-
* The initializer expects the file and function parameters to be string literals.
515+
* If no flags are passed, the method expects the file and function parameters to be string literals.
452516
* That is, it expects the given strings to exist for the duration of the object's lifetime,
453517
* and it expects the given strings to be immutable.
454518
* In other words, it does not copy these strings, it simply points to them.
519+
* This is due to the fact that __FILE__ and __FUNCTION__ are usually used to specify these parameters,
520+
* so it makes sense to optimize and skip the unnecessary allocations.
521+
* However, if you need them to be copied you may use the options parameter to specify this.
522+
* Options is a bitmask which supports DDLogMessageCopyFile and DDLogMessageCopyFunction.
455523
**/
456524
- (id)initWithLogMsg:(NSString *)logMsg
457525
level:(int)logLevel
@@ -460,7 +528,8 @@ NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
460528
file:(const char *)file
461529
function:(const char *)function
462530
line:(int)line
463-
tag:(id)tag;
531+
tag:(id)tag
532+
options:(DDLogMessageOptions)optionsMask;
464533

465534
/**
466535
* Returns the threadID as it appears in NSLog.

0 commit comments

Comments
 (0)