diff --git a/base/CLog.cpp b/base/CLog.cpp new file mode 100644 index 00000000..92a32744 --- /dev/null +++ b/base/CLog.cpp @@ -0,0 +1,110 @@ +#include "CLog.h" +#include +#include +#include + +// +// CLog +// + +void CLog::print(const char* fmt, ...) +{ + // check if fmt begins with a priority argument + int priority = 4; + if (fmt[0] == '%' && fmt[1] == 'z') { + priority = fmt[2] - '\060'; + fmt += 3; + } + + // print to buffer + char stack[1024]; + va_list args; + va_start(args, fmt); + char* buffer = vsprint(0, stack, + sizeof(stack) / sizeof(stack[0]), fmt, args); + va_end(args); + + // output buffer + output(priority, buffer); + + // clean up + if (buffer != stack) + delete[] buffer; +} + +void CLog::printt(const char* file, int line, + const char* fmt, ...) +{ + // check if fmt begins with a priority argument + int priority = 4; + if (fmt[0] == '%' && fmt[1] == 'z') { + priority = fmt[2] - '\060'; + fmt += 3; + } + + // compute prefix padding length + char stack[1024]; + sprintf(stack, "%d", line); + int pad = strlen(file) + 1 + strlen(stack) + 1 + 1; + + // print to buffer + va_list args; + va_start(args, fmt); + char* buffer = vsprint(pad, stack, + sizeof(stack) / sizeof(stack[0]), fmt, args); + va_end(args); + + // print the prefix to the buffer + sprintf(buffer, "%s,%d:", file, line); + buffer[pad - 1] = ' '; + + // output buffer + output(priority, buffer); + + // clean up + if (buffer != stack) + delete[] buffer; +} + +void CLog::output(int priority, const char* msg) +{ + static const char* s_priority[] = { + "FATAL", + "ERROR", + "WARNING", + "NOTE", + "INFO", + "DEBUG", + }; + + assert(priority >= 0 && priority < (int)(sizeof(s_priority) / + sizeof(s_priority[0]))); + assert(msg != 0); + + fprintf(stderr, "%s: %s\n", s_priority[priority], msg); +} + +char* CLog::vsprint(int pad, char* buffer, int len, + const char* fmt, va_list args) +{ + assert(len > 0); + + // try writing to input buffer + int n; + if (len >= pad) { + n = vsnprintf(buffer + pad, len - pad, fmt, args); + if (n != -1 && n <= len - pad) + return buffer; + } + + // start allocating buffers until we write the whole string + buffer = 0; + do { + delete[] buffer; + len *= 2; + buffer = new char[len + pad]; + n = vsnprintf(buffer + pad, len - pad, fmt, args); + } while (n == -1 || n > len - pad); + + return buffer; +} diff --git a/base/CLog.h b/base/CLog.h new file mode 100644 index 00000000..0d44c3e7 --- /dev/null +++ b/base/CLog.h @@ -0,0 +1,35 @@ +#ifndef CLOG_H +#define CLOG_H + +#include + +class CLog { + public: + static void print(const char*, ...); + static void printt(const char* file, int line, const char*, ...); + + private: + static void output(int priority, const char* msg); + static char* vsprint(int pad, char*, int len, const char*, va_list); + static int nprint(const char*, va_list); +}; + +#if defined(NOLOGGING) +#define log(_a1) +#define CLOG_TRACE +#elif defined(NDEBUG) +#define log(_a1) CLog::print _a1 +#define CLOG_TRACE +#else +#define log(_a1) CLog::printt _a1 +#define CLOG_TRACE __FILE__, __LINE__, +#endif + +#define CLOG_CRIT CLOG_TRACE "%z\060" +#define CLOG_ERR CLOG_TRACE "%z\061" +#define CLOG_WARN CLOG_TRACE "%z\062" +#define CLOG_NOTE CLOG_TRACE "%z\063" +#define CLOG_INFO CLOG_TRACE "%z\064" +#define CLOG_DEBUG CLOG_TRACE "%z\065" + +#endif