113 lines
3.3 KiB
C++
113 lines
3.3 KiB
C++
#pragma once
|
|
|
|
#include "pmq_base.hpp"
|
|
|
|
enum
|
|
{
|
|
PMQ_MSG_OPT_DEFAULT = 0,
|
|
PMQ_MSG_OPT_ERRNO = (1 << 0),
|
|
PMQ_MSG_HAS_SOURCE_LOC = (1 << 1),
|
|
|
|
PMQ_MSG_OPT_LVL_MASK = (3 << 2), // bits 3 and 4 for debug level.
|
|
PMQ_MSG_OPT_LVL_DEBUG = (0 << 2),
|
|
PMQ_MSG_OPT_LVL_INFO = (1 << 2),
|
|
PMQ_MSG_OPT_LVL_WARN = (2 << 2),
|
|
PMQ_MSG_OPT_LVL_ERR = (3 << 2),
|
|
};
|
|
|
|
struct PMQ_Source_Loc
|
|
{
|
|
const char *file;
|
|
uint32_t line;
|
|
};
|
|
|
|
struct PMQ_Msg_Options
|
|
{
|
|
PMQ_Source_Loc loc;
|
|
uint32_t flags; // PMQ_MSG_OPT_
|
|
int errnum;
|
|
};
|
|
|
|
|
|
// Logging functions / macros.
|
|
//
|
|
// The following functions are typically used in the client code.
|
|
//
|
|
// pmq_msg_f(fmt, ...): Submit a log message with default log level and format string + var-args
|
|
// pmq_perr_f(fmt, ...): Submit a log message with error log level and format string + var-args
|
|
// pmq_perr_ef(errno, fmt, ...): like pmq_perr_f() but also add text for given system error code ("errno")
|
|
//
|
|
// To explain all functions available here: they are made according to a pattern
|
|
//
|
|
// pmq_{LVL}_{MNEMNONICS}
|
|
//
|
|
// LVL: logging level, possible options
|
|
// - msg: Default level or use specified level ('l' mnemnonic)
|
|
// - debug: Debug level
|
|
// - warn: Warning level
|
|
// - perr: Error level ("print-error")
|
|
//
|
|
// MNEMNONICS: combination of 1-letter chars
|
|
// - l: means a logging level is specified (only available with 'msg' category)
|
|
// - e: add a text for specified system error code ("errno")
|
|
// - f: "format", like in the stdio function printf().
|
|
// - v: in combination with f (so 'fv'), means the arguments come as a va_list, like in stdio function vfprintf().
|
|
// - o: Use a single options struct holding level, errno explictly, as well as source code location info.
|
|
|
|
|
|
void pmq_msg_ofv(const PMQ_Msg_Options& opt, const char *fmt, va_list ap);
|
|
|
|
void __pmq_formatter(2, 3) pmq_msg_of(const PMQ_Msg_Options& opt, const char *fmt, ...);
|
|
|
|
#define PMQ_SOURCE_LOC ((PMQ_Source_Loc) { __FILE__, __LINE__ })
|
|
|
|
#define PMQ_MSG_OPTIONS(...) (PMQ_Msg_Options { PMQ_SOURCE_LOC, ##__VA_ARGS__ })
|
|
|
|
#define pmq_msg_lf(lvl, fmt, ...) \
|
|
pmq_msg_of(PMQ_MSG_OPTIONS((lvl), 0), fmt, ##__VA_ARGS__)
|
|
|
|
#define pmq_msg_lef(lvl, e, fmt, ...) \
|
|
pmq_msg_of(PMQ_MSG_OPTIONS(PMQ_MSG_OPT_ERRNO | (lvl), e), fmt, ##__VA_ARGS__)
|
|
|
|
#define pmq_msg_f(fmt, ...) \
|
|
pmq_msg_lf(PMQ_MSG_OPT_LVL_INFO, fmt, ##__VA_ARGS__)
|
|
|
|
#define pmq_msg_ef(e, fmt, ...) \
|
|
pmq_msg_lef(PMQ_MSG_OPT_LVL_INFO, (e), fmt, ##__VA_ARGS__)
|
|
|
|
#define pmq_debug_f(fmt, ...) \
|
|
pmq_msg_lf(PMQ_MSG_OPT_LVL_DEBUG, fmt, ##__VA_ARGS__)
|
|
|
|
#define pmq_debug_ef(e, fmt, ...) \
|
|
pmq_msg_lef(PMQ_MSG_OPT_LVL_DEBUG, (e), fmt, ##__VA_ARGS__)
|
|
|
|
#define pmq_warn_f(fmt, ...) \
|
|
pmq_msg_lf(PMQ_MSG_OPT_LVL_WARN, fmt, ##__VA_ARGS__)
|
|
|
|
#define pmq_warn_ef(e, fmt, ...) \
|
|
pmq_msg_lef(PMQ_MSG_OPT_LVL_WARN, (e), fmt, ##__VA_ARGS__)
|
|
|
|
#define pmq_perr_f(fmt, ...) \
|
|
pmq_msg_lf(PMQ_MSG_OPT_LVL_ERR, fmt, ##__VA_ARGS__)
|
|
|
|
#define pmq_perr_ef(e, fmt, ...) \
|
|
pmq_msg_lef(PMQ_MSG_OPT_LVL_ERR, (e), fmt, ##__VA_ARGS__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Low-level Logging I/O interface
|
|
|
|
struct Log_Message
|
|
{
|
|
size_t size;
|
|
char data[256 - sizeof (size_t)]; // for simplicity
|
|
};
|
|
|
|
void pmq_write_log_message(Log_Message const *input);
|
|
void pmq_read_log_message(Log_Message *output);
|
|
bool pmq_try_read_log_message_timeout_millis(Log_Message *output, int millis);
|
|
bool pmq_try_read_log_message(Log_Message *output);
|