#ifndef _PROTO_DEBUG
#define _PROTO_DEBUG
#include "protoDefs.h"
#ifdef WIN32
#include <winsock2.h>
#else
#include <string.h>
#include <errno.h>
#endif
enum ProtoDebugLevel {PL_FATAL, PL_ERROR, PL_WARN, PL_INFO, PL_DEBUG, PL_TRACE, PL_DETAIL, PL_MAX, PL_ALWAYS};
#if defined(PROTO_DEBUG) || defined(PROTO_MSG)
void SetDebugLevel(unsigned int level);
unsigned int GetDebugLevel();
bool OpenDebugLog(const char *path); void CloseDebugLog();
bool OpenDebugPipe(const char* pipeName); void CloseDebugPipe();
void ProtoDMSG(unsigned int level, const char *format, ...);
void ProtoLog(ProtoDebugLevel level, const char *format, ...);
FILE* GetDebugLog();
#ifdef WIN32
void OpenDebugWindow();
void PopupDebugWindow();
void CloseDebugWindow();
#endif #else
inline void SetDebugLevel(unsigned int level) {}
inline unsigned int GetDebugLevel() {return PL_FATAL;}
inline bool OpenDebugLog(const char *path) {return true;}
inline void CloseDebugLog() {}
inline FILE* GetDebugLog() {return stderr;}
inline bool OpenDebugPipe(const char* pipeName) {return true;}
inline void CloseDebugPipe() {}
inline void ProtoDMSG(unsigned int level, const char *format, ...) {}
inline void ProtoLog(ProtoDebugLevel level, const char *format, ...) {}
#ifdef WIN32
inline void OpenDebugWindow() {}
inline void PopupDebugWindow() {}
inline void CloseDebugWindow() {}
#endif #endif
inline void ProtoNoop() {}
#define PLOG(X, ...) ((((unsigned int)X <= ::GetDebugLevel()) || (X == PL_ALWAYS)) ? \
ProtoLog(X, ##__VA_ARGS__) : ProtoNoop())
#define DMSG(X, ...) ((unsigned int)X <= ::GetDebugLevel() ? ProtoDMSG(X, ##__VA_ARGS__) : ProtoNoop())
#if defined(PROTO_DEBUG) || defined(PROTO_MSG)
typedef void (ProtoAssertFunction)(bool condition, const char* conditionText, const char* fileName, int lineNumber, void* userData);
void SetAssertFunction(ProtoAssertFunction* assertFunction, void* userData = NULL);
void ClearAssertFunction();
bool HasAssertFunction();
void ProtoAssertHandler(bool condition, const char* conditionText, const char* fileName, int lineNumber);
void PROTO_ABORT(const char *format, ...);
#ifdef HAVE_ASSERT
#ifdef __ANDROID__
#include <android/log.h>
#define PROTO_ASSERT(X) {if (HasAssertFunction()) ProtoAssertHandler(X, #X, __FILE__, __LINE__); \
else if (!((bool)(X))) __android_log_assert(#X, "protolib", "%s line:%d", __FILE__, __LINE__);}
#else
#include <assert.h>
#define PROTO_ASSERT(X) {if (HasAssertFunction()) ProtoAssertHandler(X, #X, __FILE__, __LINE__); else assert(X);}
#endif #else
#define PROTO_ASSERT(X) \
{if (HasAssertFunction()) ProtoAssertHandler(X, #X, __FILE__, __LINE__); \
else if (!((bool)(X))) PROTO_ABORT("ASSERT(%s) failed at line %d in source file \"%s\"\n", #X, __LINE__, __FILE__);}
#endif
#ifdef TRACE
#undef TRACE
#endif void TRACE(const char *format, ...);
#else
#define PROTO_ASSERT(X)
#ifndef ABORT
#define ABORT(X)
#endif #ifndef TRACE
inline void TRACE(const char *format, ...) {}
#endif
#endif
#undef ASSERT
#define ASSERT(X) PROTO_ASSERT(X)
inline const char* GetErrorString()
{
#ifdef WIN32
static char errorString[256];
errorString[255] = '\0';
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) errorString, 255, NULL);
return errorString;
#else
return strerror(errno);
#endif }
#ifdef WIN32
typedef DWORD ProtoErrorCode;
#else
typedef int ProtoErrorCode;
#endif
inline const char* GetErrorString(ProtoErrorCode errorCode)
{
#ifdef WIN32
static char errorString[256];
errorString[255] = '\0';
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
errorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) errorString, 255, NULL);
return errorString;
#else
return strerror(errorCode);
#endif }
#endif