mirror of
https://github.com/spiffcode/hostile-takeover.git
synced 2026-02-20 09:02:00 -07:00
203 lines
5.4 KiB
C++
203 lines
5.4 KiB
C++
#ifndef __LOG_H__
|
|
#define __LOG_H__
|
|
|
|
// Compile-in logging facilities. If not turned on at compile time, the LOG
|
|
// statements will not produce any code.
|
|
//
|
|
// Two major flags:
|
|
// DEBUG_LOGGING: turns on debug logging (LOG statements). If not turned on,
|
|
// all debug LOG statements will not get compiled in.
|
|
// RELEASE_LOGGING: turns on release logging (RLOG statements). If not turned
|
|
// on, all RLOG statements will not get compled in.
|
|
|
|
// legacy: turn on LOGGING if DEBUG_LOGGING is on and vice versa. LOGGING is
|
|
// used both to turn on logging, and as a compile time conditional in existing
|
|
// code.
|
|
|
|
#if defined(LOGGING)
|
|
#if !defined(DEBUG_LOGGING)
|
|
#define DEBUG_LOGGING
|
|
#endif
|
|
#else
|
|
#if defined(DEBUG_LOGGING)
|
|
#define LOGGING
|
|
#endif
|
|
#endif
|
|
|
|
// If DEBUG_LOGGING, RELEASE_LOGGING is turned on too
|
|
#if defined(DEBUG_LOGGING)
|
|
#define RELEASE_LOGGING
|
|
#endif
|
|
|
|
// If either of these types of logging are turned on, we need CONSOLE_LOGGING
|
|
#if defined(DEBUG_LOGGING) || defined(RELEASE_LOGGING)
|
|
#define CONSOLE_LOGGING
|
|
#endif
|
|
|
|
#if !defined(DEBUG_LOGGING) || !defined(RELEASE_LOGGING)
|
|
#define EMPTY_LOGGING
|
|
#endif
|
|
|
|
#if defined(DEBUG_LOGGING)
|
|
#define LOG() base::ConsoleLog(__PRETTY_FUNCTION__, NULL, __LINE__).stream()
|
|
#define LOGF() base::ConsoleLog(__PRETTY_FUNCTION__, __FILE__, __LINE__).stream()
|
|
#define LOGS() base::ConsoleLog().stream()
|
|
#define LOGX() base::ConsoleLog(NULL, NULL, -1).stream()
|
|
#else
|
|
#define LOG() while(false) base::EmptyLog()
|
|
#define LOGF() while(false) base::EmptyLog()
|
|
#define LOGS() while(false) base::EmptyLog()
|
|
#define LOGX() while(false) base::EmptyLog()
|
|
#endif
|
|
|
|
#if defined(DEBUG_LOGGING) || defined(RELEASE_LOGGING)
|
|
#define RLOG() base::ConsoleLog(__PRETTY_FUNCTION__, NULL, __LINE__).stream()
|
|
#define RLOGF() base::ConsoleLog(__PRETTY_FUNCTION__, __FILE__, __LINE__).stream()
|
|
#define RLOGS() base::ConsoleLog().stream()
|
|
#define RLOGX() base::ConsoleLog(NULL, NULL, -1).stream()
|
|
#else
|
|
#define RLOG() while(false) base::EmptyLog()
|
|
#define RLOGF() while(false) base::EmptyLog()
|
|
#define RLOGS() while(false) base::EmptyLog()
|
|
#define RLOGX() while(false) base::EmptyLog()
|
|
#endif
|
|
|
|
// Format string compile time check
|
|
#if defined(__GNUC__) || defined(__clang__)
|
|
#define printfFormat12 __attribute__((format(printf, 1, 2)))
|
|
#else
|
|
#define printfFormat12
|
|
#endif
|
|
|
|
// Log string formatting class (for legacy reasons called Log)
|
|
|
|
#if defined(CONSOLE_LOGGING)
|
|
|
|
#include <string>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
|
|
#ifdef __ANDROID__
|
|
#include <android/log.h>
|
|
#define LOG_TAG "HT"
|
|
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
|
|
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
|
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
|
#endif
|
|
|
|
namespace base {
|
|
class Log {
|
|
public:
|
|
static std::string Format(const char *format, ...) printfFormat12 {
|
|
va_list va;
|
|
va_start(va, format);
|
|
std::string str = vFormat(format, va);
|
|
va_end(va);
|
|
return str;
|
|
}
|
|
private:
|
|
static std::string vFormat(const char *format, va_list va) {
|
|
char sz[512];
|
|
vsnprintf(sz, sizeof(sz), format, va);
|
|
return std::string(sz);
|
|
}
|
|
};
|
|
} // namespace base
|
|
|
|
#else
|
|
|
|
namespace base {
|
|
class Log {
|
|
public:
|
|
static int Format(const char *format, ...) printfFormat12 { return 0; }
|
|
};
|
|
} // namespace base
|
|
|
|
#endif // CONSOLE_LOGGING
|
|
|
|
// Empty Logging
|
|
|
|
#if defined(EMPTY_LOGGING)
|
|
namespace base {
|
|
class EmptyLog {
|
|
public:
|
|
EmptyLog() {}
|
|
EmptyLog &operator<<(const char *s) { return *this; }
|
|
EmptyLog &operator<<(int n) { return *this; }
|
|
#ifdef CONSOLE_LOGGING
|
|
EmptyLog &operator<<(const std::string& s) { return *this; }
|
|
#endif
|
|
};
|
|
} // namespace base
|
|
#endif // EMPTY_LOGGING
|
|
|
|
// Console Logging
|
|
|
|
#if defined(CONSOLE_LOGGING)
|
|
#include "inc/basictypes.h"
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <time.h>
|
|
#include <sys/time.h>
|
|
namespace base {
|
|
class ConsoleLog {
|
|
public:
|
|
ConsoleLog(const char *function, const char *file, int line) {
|
|
time_t t = time(NULL);
|
|
struct tm *tm = localtime(&t);
|
|
struct timeval tv;
|
|
gettimeofday(&tv, 0);
|
|
stream_ << Log::Format("%02d%02d%02d%02d.%02d%03d|",
|
|
tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min,
|
|
tm->tm_sec, tv.tv_usec / 1000);
|
|
|
|
if (function != NULL) {
|
|
std::string func(function);
|
|
size_t n2 = func.find('(');
|
|
if (n2 != std::string::npos) {
|
|
size_t n1 = func.rfind(' ', n2);
|
|
if (n1 != std::string::npos) {
|
|
func = std::string(func, n1 + 1, n2 - n1 - 1);
|
|
}
|
|
}
|
|
if (line == -1 && file == NULL) {
|
|
stream_ << func << "(): ";
|
|
} else {
|
|
stream_ << func << "() ";
|
|
}
|
|
}
|
|
|
|
if (line != -1) {
|
|
if (file != NULL) {
|
|
stream_ << "line " << line << " ";
|
|
} else {
|
|
stream_ << "line " << line << ": ";
|
|
}
|
|
}
|
|
|
|
if (file != NULL) {
|
|
stream_ << "file " << file << ": ";
|
|
}
|
|
}
|
|
|
|
ConsoleLog() {
|
|
}
|
|
|
|
~ConsoleLog() {
|
|
#ifdef __ANDROID__
|
|
LOGD("%s\n", stream_.str().c_str());
|
|
#else
|
|
std::cout << stream_.str() << std::endl;
|
|
#endif
|
|
}
|
|
|
|
std::ostringstream& stream() { return stream_; }
|
|
|
|
private:
|
|
std::ostringstream stream_;
|
|
};
|
|
} // namespace base
|
|
#endif // CONSOLE_LOGGING
|
|
|
|
#endif // __LOG_H__
|