29#define OOLOG_POISON_NSLOG 0
43#define PER_THREAD_INDENTATION 1
46#if PER_THREAD_INDENTATION
48 #define USE_INDENT_GLOBALS 1
49 #define THREAD_LOCAL __thread
51 #define USE_INDENT_GLOBALS 0
52 static NSString *
const kIndentLevelKey =
@"org.aegidian.oolite.oolog.indentLevel";
53 static NSString *
const kIndentStackKey =
@"org.aegidian.oolite.oolog.indentStack";
56 #define USE_INDENT_GLOBALS 1
62#define OOLOG_NOT_INITED 1
63#define OOLOG_SETTING_SET 0
64#define OOLOG_SETTING_RETRIEVE 0
65#define OOLOG_UNDEFINED_METACLASS 1
66#define OOLOG_BAD_SETTING 1
67#define OOLOG_BAD_DEFAULT_SETTING 1
68#define OOLOG_BAD_POP_INDENT 1
69#define OOLOG_EXCEPTION_IN_LOG 1
87static THREAD_LOCAL
unsigned sIndentLevel = 0;
106#define OOLogInternal(cond, format, ...) do { if ((cond)) { OOLogInternal_(OOLOG_FUNCTION_NAME, format, ## __VA_ARGS__); }} while (0)
107static void OOLogInternal_(
const char *inFunction, NSString *inFormat, ...);
120#ifndef OOLOG_NO_FILE_NAME
155 value = [sDerivedSettingsCache objectForKey:inMessageClass];
166 [sDerivedSettingsCache setObject:value forKey:inMessageClass];
169 @catch (
id exception)
189 value = [sExplicitSettings objectForKey:inClass];
194 [sExplicitSettings setObject:CacheValue(inFlag) forKey:inClass];
211 if (inClass ==
nil)
return nil;
213 range = [inClass rangeOfString:@"." options:NSCaseInsensitiveSearch | NSLiteralSearch | NSBackwardsSearch];
214 if (range.location == NSNotFound)
return nil;
216 return [inClass substringToIndex:range.location];
220#if !OOLOG_SHORT_CIRCUIT
236#if USE_INDENT_GLOBALS
239 #define INDENT_LOCK() do {} while (0)
240 #define INDENT_UNLOCK() do {} while (0)
242 #define INDENT_LOCK() [sLock lock]
243 #define INDENT_UNLOCK() [sLock unlock]
255 sIndentLevel = value;
263 elem = malloc(
sizeof *elem);
268 elem->
indent = sIndentLevel;
269 elem->
link = sIndentStack;
285 sIndentStack = elem->
link;
286 sIndentLevel = elem->
indent;
298#define INDENT_LOCK() do {} while (0)
299#define INDENT_UNLOCK() do {} while (0)
304 NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary];
305 return [[threadDict objectForKey:kIndentLevelKey] unsignedIntValue];
311 NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary];
312 [threadDict setObject:[NSNumber numberWithUnsignedInt:value] forKey:kIndentLevelKey];
319 NSMutableDictionary *threadDict =
nil;
322 elem = malloc(
sizeof *elem);
325 threadDict = [[NSThread currentThread] threadDictionary];
326 val = [threadDict objectForKey:kIndentStackKey];
328 elem->
indent = [[threadDict objectForKey:kIndentLevelKey] intValue];
329 elem->
link = [val pointerValue];
335 [threadDict setObject:[NSValue valueWithPointer:elem] forKey:kIndentStackKey];
343 NSMutableDictionary *threadDict =
nil;
346 threadDict = [[NSThread currentThread] threadDictionary];
347 val = [threadDict objectForKey:kIndentStackKey];
349 elem = [val pointerValue];
353 [threadDict setObject:[NSNumber numberWithUnsignedInt:elem->indent] forKey:kIndentLevelKey];
354 [threadDict setObject:[NSValue valueWithPointer:elem->link] forKey:kIndentStackKey];
387void OOLogWithPrefix(NSString *inMessageClass,
const char *inFunction,
const char *inFile,
unsigned long inLine, NSString *inPrefix, NSString *inFormat, ...)
391 va_start(args, inFormat);
401 va_start(args, inFormat);
409 NSAutoreleasePool *pool =
nil;
410 NSString *formattedMessage =
nil;
411 unsigned indentLevel;
413 if (inFormat ==
nil)
return;
415#if !OOLOG_SHORT_CIRCUIT
419 pool = [[NSAutoreleasePool alloc] init];
423 formattedMessage = [[[NSString alloc] initWithFormat:inFormat arguments:inArguments] autorelease];
426 #ifndef OOLOG_NO_FILE_NAME
431 formattedMessage = [NSString stringWithFormat:@"%s (%@:%lu): %@", inFunction, OOLogAbbreviatedFileName(inFile), inLine, formattedMessage];
435 formattedMessage = [NSString stringWithFormat:@"%@:%lu: %@", OOLogAbbreviatedFileName(inFile), inLine, formattedMessage];
443 formattedMessage = [NSString stringWithFormat:@"%s: %@", inFunction, formattedMessage];
451 formattedMessage = [NSString stringWithFormat:@"[%@] %@", inMessageClass, formattedMessage];
455 formattedMessage = [NSString stringWithFormat:@"[%@]: %@", inMessageClass, formattedMessage];
461 formattedMessage = [NSString stringWithFormat:@"%@ %@", [[NSDate date] descriptionWithCalendarFormat:@"%H:%M:%S.%F" timeZone:nil locale:nil], formattedMessage];
466 if (indentLevel != 0)
468 #define INDENT_FACTOR 2
469 #define MAX_INDENT 64
473 const char spaces[MAX_INDENT + 1] =
475 const char *indentString;
479 indentString = &spaces[MAX_INDENT - indent];
481 formattedMessage = [NSString stringWithFormat:@"%s%@", indentString, formattedMessage];
486 @catch (NSException *exception)
497 OOLog(
kOOLogParameterError,
@"***** %s: bad parameters. (This is an internal programming error, please report it.)", inFunction);
520 [[NSUserDefaults standardUserDefaults] setBool:flag forKey:@"logging-show-function"];
538 [[NSUserDefaults standardUserDefaults] setBool:flag forKey:@"logging-show-file-and-line"];
556 [[NSUserDefaults standardUserDefaults] setBool:flag forKey:@"logging-show-time"];
574 [[NSUserDefaults standardUserDefaults] setBool:flag forKey:@"logging-show-class"];
587 NSAutoreleasePool *pool =
nil;
591 pool = [[NSAutoreleasePool alloc] init];
593 sLock = [[NSLock alloc] init];
594 [sLock setName:@"OOLogging lock"];
595 if (
sLock ==
nil) exit(EXIT_FAILURE);
597#ifndef OOLOG_NO_FILE_NAME
598 sFileNamesCache = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks, NSObjectMapValueCallBacks, 100);
634 static unsigned lastMarkerID = 0;
635 unsigned thisMarkerID;
636 NSString *marker =
nil;
639 thisMarkerID = ++lastMarkerID;
642 marker = [NSString stringWithFormat:@"\n\n========== [Marker %u] ==========", thisMarkerID];
665 NSString *formattedMessage =
nil;
666 NSAutoreleasePool *pool =
nil;
668 pool = [[NSAutoreleasePool alloc] init];
672 va_start(args, inFormat);
673 formattedMessage = [[[NSString alloc] initWithFormat:inFormat arguments:args] autorelease];
676 formattedMessage = [NSString stringWithFormat:@"OOLogging internal - %s: %@", inFunction, formattedMessage];
680 @catch (NSException *exception)
682 fprintf(stderr,
"***** Exception in OOLogInternal_(): %s : %s", [[exception name] UTF8String], [[exception reason] UTF8String]);
708 NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
709 sShowFunction = [prefs oo_boolForKey:@"logging-show-function" defaultValue:NO];
710 sShowFileAndLine = [prefs oo_boolForKey:@"logging-show-file-and-line" defaultValue:NO];
711 sShowTime = [prefs oo_boolForKey:@"logging-show-time" defaultValue:YES];
712 sShowClass = [prefs oo_boolForKey:@"logging-show-class" defaultValue:YES];
723 stringByAppendingPathComponent:@"logcontrol.plist"];
728 [oldSettings release];
740 id value = [sExplicitSettings objectForKey:@"_default"];
741 if (value !=
nil && [value respondsToSelector:
@selector(boolValue)])
747 [sExplicitSettings removeObjectForKey:@"_default"];
749 value = [sExplicitSettings objectForKey:@"_override"];
750 if (value !=
nil && [value respondsToSelector:
@selector(boolValue)])
764 [sExplicitSettings removeObjectForKey:@"_override"];
782 id value = [inDict objectForKey:key];
791 if ([value isKindOfClass:[NSString
class]])
793 if (NSOrderedSame == [value caseInsensitiveCompare:
@"yes"] ||
794 NSOrderedSame == [value caseInsensitiveCompare:
@"true"] ||
795 NSOrderedSame == [value caseInsensitiveCompare:
@"on"])
799 else if (NSOrderedSame == [value caseInsensitiveCompare:
@"no"] ||
800 NSOrderedSame == [value caseInsensitiveCompare:
@"false"] ||
801 NSOrderedSame == [value caseInsensitiveCompare:
@"off"])
805 else if (NSOrderedSame == [value caseInsensitiveCompare:
@"inherit"] ||
806 NSOrderedSame == [value caseInsensitiveCompare:
@"inherited"])
809 [sExplicitSettings removeObjectForKey:key];
811 else if (![value hasPrefix:
@"$"])
817 else if ([value respondsToSelector:
@selector(boolValue)])
829 [sExplicitSettings setObject:value forKey:key];
841 NSString *name =
nil;
843 if (
EXPECT_NOT(inName == NULL))
return @"unspecified file";
849 name = [[NSString stringWithUTF8String:inName] lastPathComponent];
864 NSMutableSet *seenMetaClasses =
nil;
868 value = [sExplicitSettings objectForKey:inMessageClass];
877 seenMetaClasses = [NSMutableSet set];
890 if (![inMetaClass isKindOfClass:[NSString
class]] || ![inMetaClass hasPrefix:
@"$"])
896 [ioSeenMetaClasses addObject:inMetaClass];
898 value = [sExplicitSettings objectForKey:inMetaClass];
#define foreachkey(VAR, DICT)
void OOLogOutputHandlerPrint(NSString *string)
void OOLogOutputHandlerClose(void)
void OOLogOutputHandlerInit(void)
#define OOLogOutdentIf(class)
#define OOLog(class, format,...)
#define OOLogIndentIf(class)
static BOOL sShowFunction
void OOLogPushIndent(void)
static NSString *const kFalseToken
NSString *const kOOLogException
NSString *const kOOLogOpenGLError
NSString *const kOOLogInconsistentState
NSString *const kOOLogDeprecatedMethod
void OOLoggingTerminate(void)
static NSMutableDictionary * sExplicitSettings
OOINLINE unsigned GetIndentLevel(void) PURE_FUNC
OOINLINE void SetIndentLevel(unsigned level)
void OOLogPopIndent(void)
static NSString *const kTrueToken
static void LoadExplicitSettings(void)
void OOLogWithPrefix(NSString *inMessageClass, const char *inFunction, const char *inFile, unsigned long inLine, NSString *inPrefix, NSString *inFormat,...)
BOOL OOLogWillDisplayMessagesInClass(NSString *inMessageClass)
#define OOLOG_BAD_DEFAULT_SETTING
void OOLogWithFunctionFileAndLine(NSString *inMessageClass, const char *inFunction, const char *inFile, unsigned long inLine, NSString *inFormat,...)
void OOLogSetShowFileAndLine(BOOL flag)
#define OOLOG_SETTING_RETRIEVE
void OOLogSetShowTime(BOOL flag)
void OOLogSetShowFunction(BOOL flag)
void OOLogWithFunctionFileAndLineAndArguments(NSString *inMessageClass, const char *inFunction, const char *inFile, unsigned long inLine, NSString *inFormat, va_list inArguments)
static BOOL sOverrideValue
BOOL OOLogShowFunction(void)
NSString *const kOOLogFileNotLoaded
OOINLINE BOOL Inited(void)
static NSString *const kIndentStackKey
static BOOL sShowFileAndLine
void OOLoggingReloadSettings(void)
void OOLogGenericSubclassResponsibilityForFunction(const char *inFunction)
#define OOLOG_EXCEPTION_IN_LOG
#define OOLOG_SETTING_SET
BOOL OOLogShowMessageClass(void)
NSString * OOLogAbbreviatedFileName(const char *inName)
#define OOLogInternal(cond, format,...)
static BOOL sOverrideInEffect
static NSString *const kIndentLevelKey
void OOLogSetDisplayMessagesInClass(NSString *inClass, BOOL inFlag)
OOINLINE id CacheValue(BOOL inValue) PURE_FUNC
static void LoadExplicitSettingsFromDictionary(NSDictionary *inDict)
#define OOLOG_UNDEFINED_METACLASS
NSString *const kOOLogAllocationFailure
NSString *const kOOLogParameterError
static id ResolveDisplaySetting(NSString *inMessageClass)
#define OOLOG_BAD_POP_INDENT
NSString *const kOOLogUnconvertedNSLog
NSString *const kOOLogFileNotFound
static void OOLogInternal_(const char *inFunction, NSString *inFormat,...)
#define OOLOG_BAD_SETTING
void OOLogInsertMarker(void)
NSString *const kOOLogSubclassResponsibility
NSString * OOLogGetParentMessageClass(NSString *inClass)
static NSString *const kInheritToken
void OOLogSetShowMessageClass(BOOL flag)
static NSMapTable * sFileNamesCache
static BOOL sDefaultDisplay
static NSMutableDictionary * sDerivedSettingsCache
static id ResolveMetaClassReference(NSString *inMetaClass, NSMutableSet *ioSeenMetaClasses)
void OOLogSetShowMessageClassTemporary(BOOL flag)
BOOL OOLogShowFileAndLine(void)
void OOLogGenericParameterErrorForFunction(const char *inFunction)
NSDictionary * OODictionaryFromFile(NSString *path)
NSDictionary * logControlDictionary()