nuclear@13: #include nuclear@13: #include nuclear@13: #include "logger.h" nuclear@13: nuclear@13: #if defined(unix) || defined(__unix__) || defined(__APPLE__) nuclear@13: #include nuclear@13: #elif defined(WIN32) nuclear@13: #include nuclear@13: #endif nuclear@13: nuclear@13: enum { LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_FATAL, LOG_DEBUG }; nuclear@13: nuclear@13: static int typecolor(int type); nuclear@13: nuclear@13: static FILE *fp = stdout; nuclear@13: nuclear@13: static void logmsg(int type, const char *fmt, va_list ap) nuclear@13: { nuclear@13: #if defined(unix) || defined(__unix__) || (defined(__APPLE__) && !defined(TARGET_IPHONE)) nuclear@13: if(isatty(fileno(fp)) && type != LOG_INFO) { nuclear@13: int c = typecolor(type); nuclear@13: fprintf(fp, "\033[%dm", c); nuclear@13: vfprintf(fp, fmt, ap); nuclear@13: fprintf(fp, "\033[0m"); nuclear@13: } else nuclear@13: #endif nuclear@13: { nuclear@13: vfprintf(fp, fmt, ap); nuclear@13: } nuclear@13: if(type == LOG_ERROR || type == LOG_FATAL || type == LOG_DEBUG) { nuclear@13: fflush(fp); nuclear@13: } nuclear@13: nuclear@13: #ifdef WIN32 nuclear@13: if(type == LOG_FATAL) { nuclear@13: static char msgbuf[1024]; nuclear@13: vsnprintf(msgbuf, sizeof msgbuf - 1, fmt, ap); nuclear@13: msgbuf[sizeof msgbuf - 1] = 0; nuclear@13: MessageBox(0, msgbuf, "Fatal error", MB_OK | MB_ICONSTOP); nuclear@13: } nuclear@13: #endif nuclear@13: } nuclear@13: nuclear@13: void info_log(const char *fmt, ...) nuclear@13: { nuclear@13: va_list ap; nuclear@13: nuclear@13: va_start(ap, fmt); nuclear@13: logmsg(LOG_INFO, fmt, ap); nuclear@13: va_end(ap); nuclear@13: } nuclear@13: nuclear@13: void warning_log(const char *fmt, ...) nuclear@13: { nuclear@13: va_list ap; nuclear@13: nuclear@13: va_start(ap, fmt); nuclear@13: logmsg(LOG_WARNING, fmt, ap); nuclear@13: va_end(ap); nuclear@13: } nuclear@13: nuclear@13: void error_log(const char *fmt, ...) nuclear@13: { nuclear@13: va_list ap; nuclear@13: nuclear@13: va_start(ap, fmt); nuclear@13: logmsg(LOG_ERROR, fmt, ap); nuclear@13: va_end(ap); nuclear@13: } nuclear@13: nuclear@13: void fatal_log(const char *fmt, ...) nuclear@13: { nuclear@13: va_list ap; nuclear@13: nuclear@13: va_start(ap, fmt); nuclear@13: logmsg(LOG_FATAL, fmt, ap); nuclear@13: va_end(ap); nuclear@13: } nuclear@13: nuclear@13: void debug_log(const char *fmt, ...) nuclear@13: { nuclear@13: va_list ap; nuclear@13: nuclear@13: va_start(ap, fmt); nuclear@13: logmsg(LOG_DEBUG, fmt, ap); nuclear@13: va_end(ap); nuclear@13: } nuclear@13: nuclear@13: enum { nuclear@13: BLACK = 0, nuclear@13: RED, nuclear@13: GREEN, nuclear@13: YELLOW, nuclear@13: BLUE, nuclear@13: MAGENTA, nuclear@13: CYAN, nuclear@13: WHITE nuclear@13: }; nuclear@13: nuclear@13: #define ANSI_FGCOLOR(x) (30 + (x)) nuclear@13: #define ANSI_BGCOLOR(x) (40 + (x)) nuclear@13: nuclear@13: static int typecolor(int type) nuclear@13: { nuclear@13: switch(type) { nuclear@13: case LOG_ERROR: nuclear@13: return ANSI_FGCOLOR(RED); nuclear@13: case LOG_FATAL: nuclear@13: return ANSI_FGCOLOR(RED); // TODO differentiate from LOG_ERROR nuclear@13: case LOG_WARNING: nuclear@13: return ANSI_FGCOLOR(YELLOW); nuclear@13: case LOG_DEBUG: nuclear@13: return ANSI_FGCOLOR(MAGENTA); nuclear@13: default: nuclear@13: break; nuclear@13: } nuclear@13: return 37; nuclear@13: }