27#ifndef PROTOCORE_LOG_H
28#define PROTOCORE_LOG_H
46#define PC_LOG_DISCARD(...) \
49 (void)sizeof(pc_log_discard_args(__VA_ARGS__)); \
52#if PC_LOG_LEVEL < PC_LOG_LEVEL_NONE
61void pc_log_frame(uint8_t level,
const pc_field *spec, ...);
76#if PC_LOG_LEVEL <= PC_LOG_LEVEL_DEBUG
77#define PC_LOGD(...) pc_log_frame(PC_LOG_LEVEL_DEBUG, __VA_ARGS__)
79#define PC_LOGD(...) PC_LOG_DISCARD(__VA_ARGS__)
82#if PC_LOG_LEVEL <= PC_LOG_LEVEL_INFO
83#define PC_LOGI(...) pc_log_frame(PC_LOG_LEVEL_INFO, __VA_ARGS__)
85#define PC_LOGI(...) PC_LOG_DISCARD(__VA_ARGS__)
88#if PC_LOG_LEVEL <= PC_LOG_LEVEL_WARN
89#define PC_LOGW(...) pc_log_frame(PC_LOG_LEVEL_WARN, __VA_ARGS__)
91#define PC_LOGW(...) PC_LOG_DISCARD(__VA_ARGS__)
94#if PC_LOG_LEVEL <= PC_LOG_LEVEL_ERROR
95#define PC_LOGE(...) pc_log_frame(PC_LOG_LEVEL_ERROR, __VA_ARGS__)
97#define PC_LOGE(...) PC_LOG_DISCARD(__VA_ARGS__)
Declarative frame builder: a frame is a static table of typed fields, built by one engine.
void(* pc_log_sink_fn)(uint8_t level, const char *line)
Receives an emitted line, already formatted. level is a PC_LOG_LEVEL_* value.
int pc_log_discard_args(const pc_field *spec,...)
Declared, never defined: only ever named inside sizeof, so no call is ever generated.
User-facing configuration for ProtoCore.
One field of a frame. Frames are static const pc_field[], so they live in rodata.