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;
}
Exemple #3
0
/** 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