#include
struct LogMessageEnvelope{
enum Severity{
kAssertFailed = -3,
kError = -2,
kWarning = -1,
kInfo = 0
};
int severity;
};
int A(LogMessageEnvelope::Severity severity){
std::cout << severity << std::endl;
}
int main(){
A(LogMessageEnvelope::kError);
return 0;
}
-2
例1:
#include
#include
#include
namespace k{
struct LogMessageEnvelope{
enum Severity{
kAssertFailed = -3,
kError = -2,
kWarning = -1,
kInfo = 0
};
int severity;
const char *func;
const char *file;
int line;
};
}
static std::string program_name;
void SetProgramName(const char *basename) {
program_name = basename;
}
typedef void (*LogHandler)(const ::k::LogMessageEnvelope &envelope,const char *message);
static LogHandler log_handler = NULL;
static const char *GetShortFileName(const char *path) {
if (path == nullptr)
return "";
const char *prev = path, *last = path;
while ((path = strpbrk(path, "\\/")) != nullptr) {
++path;
prev = last;
last = path;
}
return prev;
}
namespace k{
inline int GetVerboseLevel(){return 5;}
class Kfatalerror:public std::runtime_error{
public:
explicit Kfatalerror(const std::string &message):std::runtime_error(message){}
explicit Kfatalerror(const char *message):std::runtime_error(message){}
virtual const char *what() const noexcept override{
return "Kfatalerror";
}
const char *KMessage() const {
return std::runtime_error::what();
}
};
class MessageLogger{
public:
MessageLogger(LogMessageEnvelope::Severity severity,const char *func, const char *file, int line) {
envelope_.severity = severity;
envelope_.func = func;
envelope_.file = GetShortFileName(file);
envelope_.line = line;
}
template MessageLogger &operator<<(const T &val){
ss_ << val;
return *this;
}
struct Log final{
void operator=(const MessageLogger &logger){
logger.LogMessage();
}
};
struct LogAndThrow final{
[[noreturn]] void operator=(const MessageLogger &logger){
logger.LogMessage();
throw Kfatalerror(logger.GetMessage());
}
};
private:
std::string GetMessage() const { return ss_.str();}
void LogMessage() const {
if (log_handler != NULL) {
log_handler(envelope_, GetMessage().c_str());
return;
}
std::stringstream full_message;
if (envelope_.severity > LogMessageEnvelope::kInfo) {
full_message << "VLOG[" << envelope_.severity << "] (";
} else {
std::cout << envelope_.severity << std::endl;
std::cout << LogMessageEnvelope::kWarning << std::endl;
switch (envelope_.severity) {
case LogMessageEnvelope::kInfo:
full_message << "LOG (";
break;
case LogMessageEnvelope::kWarning:
full_message << "WARNING (";
break;
case LogMessageEnvelope::kAssertFailed:
full_message << "ASSERTION_FAILED (";
break;
case LogMessageEnvelope::kError:
default:
full_message << "ERROR (";
break;
}
}
full_message << program_name.c_str() << "[" "4" "]" << ':' << envelope_.func << "():" << envelope_.file << ':' << envelope_.line << ") " << GetMessage().c_str();
if (envelope_.severity < LogMessageEnvelope::kWarning) {
}
full_message << "\n";
std::cerr << full_message.str();
}
LogMessageEnvelope envelope_;
std::ostringstream ss_;
};
#define KERR k::MessageLogger::LogAndThrow() = k::MessageLogger(::k::LogMessageEnvelope::kError,__func__,__FILE__,__LINE__)
#define KWARN k::MessageLogger::Log() = k::MessageLogger(k::LogMessageEnvelope::kWarning,__func__,__FILE__,__LINE__)
#define KLOG k::MessageLogger::Log() = ::k::MessageLogger(k::LogMessageEnvelope::kInfo,__func__,__FILE__,__LINE__)
#define KASSERT(cond) \
do { \
if (cond) \
(void)0; \
else \
::k::KAssertFailure_(__func__, __FILE__, __LINE__, #cond); \
} while (0)
#define KVLOG(v) \
if ((v) <= ::k::GetVerboseLevel()) \
k::MessageLogger::Log() = ::k::MessageLogger((::k::LogMessageEnvelope::Severity)(v),__func__, __FILE__, __LINE__)
namespace internal {
bool LocateSymbolRange(const std::string &trace_name, size_t *begin,size_t *end) {
*begin = std::string::npos;
for (size_t i = 1; i < trace_name.size(); i++) {
if (trace_name[i] != '_') {
continue;
}
if (trace_name[i - 1] == ' ' || trace_name[i - 1] == '(') {
*begin = i;
break;
}
}
if (*begin == std::string::npos) {
return false;
}
*end = trace_name.find_first_of(" +", *begin);
return *end != std::string::npos;
}
}
}
namespace k{
void KAssertFailure_(const char *func, const char *file, int line,const char *cond_str) {
k::MessageLogger::Log() = k::MessageLogger(k::LogMessageEnvelope::kAssertFailed, func, file, line)<< "Assertion failed: (" << cond_str << ")";
fflush(NULL);
std::abort();
}
}
LogHandler SetLogHandler(LogHandler handler) {
LogHandler old_handler = log_handler;
log_handler = handler;
return old_handler;
}
int main(){
const std::string trace="132 _1312 +231";
SetProgramName("kerror");
size_t begin,end;
const bool found = k::internal::LocateSymbolRange(trace, &begin, &end);
std::cout << found << std::endl;
if (found) {
KVLOG(2) << "Found mismatch, got " << found << " want ";
}
KASSERT(0);
return 0;
}
1
VLOG[2] (kerror[4]:main():kerror.cpp:196) Found mismatch, got 1 want
-3
-1
ASSERTION_FAILED (kerror[4]:main():kerror.cpp:198) Assertion failed: (0)
已放弃 (核心已转储)