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