int spp::vprintf(PrintMode printMode, const char* fmt, va_list args) { FILE* stream = stdout; setTerminalColor(printMode); switch(printMode) { case kPrintError: ::printf("ERROR: "); stream = stderr; break; default: break; } int ret = ::vfprintf(stream, fmt, args); setTerminalColor(spp::kPrintNormal); return ret; }
char* spp::gets(char* str, size_t n, bool displayHeader) { setTerminalColor(spp::kPrintBoring); if( displayHeader ) { gets_mtx.lock(); headerDisplaying = true; fputs(header, stdout); gets_mtx.unlock(); } fgets(str, n, stdin); gets_mtx.lock(); headerDisplaying = false; gets_mtx.unlock(); // Remove trailing newline, or don't if fgets returned because n was reached. int pos = strlen(str) - 1; if(str[pos] == '\n') { str[pos] = '\0'; } setTerminalColor(spp::kPrintNormal); return str; }
/** This actually prints the log message. If log messages are not redirected * to a file, it tries to select a terminal colour. * \param level Log level of the message to print. * \param format A printf-like format string. * \param va_list The values to be printed for the format. */ void Log::printMessage(int level, const char *component, const char *format, VALIST args) { assert(level>=0 && level <=LL_FATAL); if(level<m_min_log_level) return; #ifdef ANDROID android_LogPriority alp; switch (level) { // STK is using the levels slightly different from android // (debug lowest, verbose above it; while android reverses // this order. So to get the same behaviour (e.g. filter // out debug message, but still get verbose, we swap // the order here. case LL_VERBOSE: alp = ANDROID_LOG_DEBUG; break; case LL_DEBUG: alp = ANDROID_LOG_VERBOSE; break; case LL_INFO: alp = ANDROID_LOG_INFO; break; case LL_WARN : alp = ANDROID_LOG_WARN; break; case LL_ERROR: alp = ANDROID_LOG_ERROR; break; case LL_FATAL: alp = ANDROID_LOG_FATAL; break; default: alp = ANDROID_LOG_FATAL; } __android_log_vprint(alp, "SuperTuxKart", format, args); #else static const char *names[] = {"verbose", "debug ", "info ", "warn ", "error ", "fatal "}; // Using a va_list twice produces undefined results, ie crash. // So make a copy if we're going to use it twice. VALIST copy; if (m_file_stdout) { va_copy(copy, args); } #if defined(_MSC_FULL_VER) && defined(_DEBUG) VALIST copy2; va_copy(copy2, args); #endif // If we don't have a console file, write to stdout and hope for the best if(!m_file_stdout || level >= LL_WARN || UserConfigParams::m_log_errors_to_console) // log to console & file { VALIST out; va_copy(out, args); setTerminalColor((LogLevel)level); printf("[%s] %s: ", names[level], component); vprintf(format, out); resetTerminalColor(); // this prints a \n va_end(out); } #if defined(_MSC_FULL_VER) && defined(_DEBUG) static char szBuff[2048]; vsnprintf(szBuff, sizeof(szBuff), format, copy2); OutputDebugString("["); OutputDebugString(names[level]); OutputDebugString("] "); OutputDebugString(component); OutputDebugString(": "); OutputDebugString(szBuff); OutputDebugString("\r\n"); #endif if(m_file_stdout) { fprintf (m_file_stdout, "[%s] %s: ", names[level], component); vfprintf(m_file_stdout, format, copy); fprintf (m_file_stdout, "\n"); va_end(copy); } #endif } // printMessage