#include <stdio.h>
+#include <stdlib.h>
#include <stdarg.h>
#include "logger.h"
#include "ui.h"
enum { LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_FATAL, LOG_DEBUG };
static int typecolor(int type);
+static const char *typeprefix(int type);
static FILE *fp = stdout;
+static FILE *logfile;
static void logmsg(int type, const char *fmt, va_list ap)
{
+ va_list ap_orig;
+
+ va_copy(ap_orig, ap);
+
#if defined(unix) || defined(__unix__) || (defined(__APPLE__) && !defined(TARGET_IPHONE))
if(isatty(fileno(fp)) && type != LOG_INFO) {
int c = typecolor(type);
} else
#endif
{
+ fprintf(fp, "%s", typeprefix(type));
vfprintf(fp, fmt, ap);
}
if(type == LOG_ERROR || type == LOG_FATAL || type == LOG_DEBUG) {
fflush(fp);
}
+ if(logfile) {
+ va_end(ap);
+ va_copy(ap, ap_orig);
+ fprintf(logfile, "%s", typeprefix(type));
+ vfprintf(logfile, fmt, ap);
+ }
+
#ifdef WIN32
if(type == LOG_FATAL) {
static char msgbuf[1024];
- vsnprintf(msgbuf, sizeof msgbuf - 1, fmt, ap);
+ vsnprintf(msgbuf, sizeof msgbuf - 1, fmt, ap_orig);
msgbuf[sizeof msgbuf - 1] = 0;
MessageBox(0, msgbuf, "Fatal error", MB_OK | MB_ICONSTOP);
}
#endif
+
+ va_end(ap_orig);
+}
+
+static void close_logfile(void)
+{
+ if(logfile) fclose(logfile);
+}
+
+extern "C" void set_log_file(const char *fname)
+{
+ static int init_once;
+
+ close_logfile();
+ logfile = fopen(fname, "w");
+
+ if(!init_once) {
+ atexit(close_logfile);
+ init_once = 1;
+ }
}
extern "C" void info_log(const char *fmt, ...)
}
return 37;
}
+
+static const char *typeprefix(int type)
+{
+ switch(type) {
+ case LOG_ERROR:
+ return "E: ";
+ case LOG_FATAL:
+ return "F: ";
+ case LOG_WARNING:
+ return "W: ";
+ case LOG_DEBUG:
+ return "D: ";
+ default:
+ break;
+ }
+ return "";
+}