// Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 #ifdef _DEBUG #include #include #include #include #include #if defined(OSMac_) && !defined(OSMac_MachO_) #include "shaveMacCarbon.h" #endif #include "shaveDebug.h" bool shaveDebug::mInitialized = false; FILE* shaveDebug::mLogFile = NULL; MStringArray shaveDebug::mStack; unsigned int shaveDebug::mStackDepth = 0; void shaveDebug::enter( MString method, unsigned int lineNumber, const char* file ) { init(); if (mLogFile) { outputHeader("ENTER", method, lineNumber, file); fputc('\n', mLogFile); fflush(mLogFile); if (mStackDepth < mStack.length()) mStack[mStackDepth] = method; else mStack.append(method); } mStackDepth++; } void shaveDebug::indent() { init(); if (mLogFile) { unsigned int i; for (i = 0; i < mStackDepth; i++) fputs(" ", mLogFile); fflush(mLogFile); } } void shaveDebug::init() { if (!mInitialized) { const char* logFilePath; mInitialized = true; #if defined(OSMac_) && !defined(OSMac_MachO_) MString temp; MGlobal::executeCommand("getenv SHAVE_DEBUG_LOG", temp); temp = shaveMacCarbon::makeMacFilename(temp); logFilePath = temp.asChar(); #else logFilePath = getenv("SHAVE_DEBUG_LOG"); #endif if (logFilePath) mLogFile = fopen(logFilePath, "w"); } } void shaveDebug::leave( MString method, unsigned int lineNumber, const char* file ) { bool unbalanced = (mStackDepth == 0); init(); if (mStackDepth > 0) mStackDepth--; if (mLogFile) { if (!unbalanced && (method != mStack[mStackDepth])) fprintf(mLogFile, "ERROR: enter/leave method mismatch!\n"); outputHeader("LEAVE", method, lineNumber, file); fputc('\n', mLogFile); if (unbalanced) { fprintf( mLogFile, "ERROR: leaving more levels than were entered!\n" ); } fflush(mLogFile); } } void shaveDebug::logMsg( MString msg, unsigned int lineNumber, const char* file ) { init(); if (mLogFile) { MString method = "???"; if ((mStackDepth > 0) && (mStackDepth <= mStack.length())) method = mStack[mStackDepth - 1]; outputHeader("INFO", method, lineNumber, file); fprintf(mLogFile, "%s\n", msg.asChar()); fflush(mLogFile); } } void shaveDebug::outputHeader( const char* tag, MString method, unsigned int lineNumber, const char* file ) { indent(); // // Get rid of the directory path from the filename. // #ifdef _WIN32 const char* nameOnly = strrchr(file, '\\'); #else #ifdef OSMac_ const char* nameOnly = strrchr(file, '/'); #else const char* nameOnly = rindex(file, '/'); #endif #endif if (nameOnly == NULL) nameOnly = file; else nameOnly++; fprintf( mLogFile, "%s [%s, %s:%d]: ", tag, method.asChar(), nameOnly, lineNumber ); } #endif