- 添加 SCC_AST_DECL_LIST 节点类型用于表示声明列表 - 实现 scc_ast_decl_list_init 函数来初始化声明列表节点 - 重构 scc_parse_declaration 函数以支持逗号分隔的多个变量声明 - 分离类型说明符解析到独立的 scc_parse_declaration_specifiers 函数 - 支持 typedef 和多变量声明如 'int a, b;' 和 'int a = 1, b = 2;' - 在 ast_dump 中添加对声明列表节点的打印支持 refactor(ast): 统一使用 scc_vec_foreach 宏替换手动循环 - 将 ast_dump.c 中的多个手动索引循环改为使用 scc_vec_foreach - 提高代码可读性和安全性 - 避免索引越界错误 fix(parser): 修复语义分析中结构体符号表冲突 - 为结构体、联合体和枚举符号名添加前缀避免命名冲突 - 使用 '$S_'、'$U_'、'$E_' 前缀分别标识结构体、联合体和枚举 refactor(log): 统一终止处理方式 - 将 log_exit 替换为 log_abort 以更准确反映行为 - 更新相关依赖模块的实现 style(parser): 移除未使用的参数和清理代码 - 在 argparse.c 中添加 (void) 参数注释处理未使用的参数 - 清理 parse_expr.c 中未使用的函数声明 - 优化 parse_type.c 中的错误处理流程
93 lines
2.9 KiB
C
93 lines
2.9 KiB
C
#include <log.h>
|
|
|
|
static inline int log_snprintf(char *s, size_t n, const char *format, ...) {
|
|
int ret;
|
|
va_list args;
|
|
va_start(args, format);
|
|
ret = log_vsnprintf(s, n, format, args);
|
|
va_end(args);
|
|
return ret;
|
|
}
|
|
|
|
int log_default_handler(logger_t *module, log_level_t level, const char *file,
|
|
int line, const char *func, const char *fmt, ...) {
|
|
const char *level_str;
|
|
int offset = 0;
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
/* clang-format off */
|
|
switch (level) {
|
|
case LOG_LEVEL_DEBUG: level_str = "DEBUG"; break;
|
|
case LOG_LEVEL_INFO: level_str = "INFO "; break;
|
|
case LOG_LEVEL_WARN: level_str = "WARN "; break;
|
|
case LOG_LEVEL_ERROR: level_str = "ERROR"; break;
|
|
case LOG_LEVEL_FATAL: level_str = "FATAL"; break;
|
|
case LOG_LEVEL_TRACE: level_str = "TRACE"; break;
|
|
default: level_str = "NOTSET"; break;
|
|
}
|
|
/// @note: 定义 __LOG_NO_COLOR__ 会取消颜色输出
|
|
#ifndef __LOG_NO_COLOR__
|
|
const char *color_code;
|
|
switch (level) {
|
|
case LOG_LEVEL_DEBUG: color_code = ANSI_FG_CYAN; break;
|
|
case LOG_LEVEL_INFO: color_code = ANSI_FG_GREEN; break;
|
|
case LOG_LEVEL_TRACE: color_code = ANSI_FG_BLUE; break;
|
|
case LOG_LEVEL_WARN: color_code = ANSI_FG_YELLOW; break;
|
|
case LOG_LEVEL_ERROR: color_code = ANSI_FG_RED; break;
|
|
case LOG_LEVEL_FATAL: color_code = ANSI_FG_RED ANSI_UNDERLINED; break;
|
|
default: color_code = ANSI_NONE;
|
|
}
|
|
/* clang-format on */
|
|
offset =
|
|
log_snprintf(module->buf, sizeof(module->buf),
|
|
ANSI_BOLD "%s[%s] %s - %s:%d in %s()" ANSI_NONE " ",
|
|
color_code, level_str, module->name, file, line, func);
|
|
#else
|
|
offset = log_snprintf(module->buf, sizeof(module->buf),
|
|
"[%s] %s - %s:%d in %s() ", level_str, module->name,
|
|
file, line, func);
|
|
#endif
|
|
/* 然后写入用户消息(如果有) */
|
|
if (fmt && fmt[0]) {
|
|
log_vsnprintf(module->buf + offset, sizeof(module->buf) - offset, fmt,
|
|
args);
|
|
}
|
|
va_end(args);
|
|
log_puts(module->buf);
|
|
log_puts("\n");
|
|
// for clangd warning
|
|
// clang-analyzer-deadcode.DeadStores
|
|
(void)color_code;
|
|
(void)level_str;
|
|
if (level & LOG_LEVEL_FATAL) {
|
|
log_abort();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
logger_t __default_logger_root = {
|
|
.name = "root",
|
|
.level = LOG_LEVEL_ALL,
|
|
.handler = log_default_handler,
|
|
};
|
|
|
|
void init_logger(logger_t *logger, const char *name) {
|
|
logger->name = name;
|
|
logger->handler = log_default_handler;
|
|
log_set_level(logger, LOG_LEVEL_ALL);
|
|
}
|
|
|
|
void log_set_level(logger_t *logger, int level) {
|
|
if (logger)
|
|
logger->level = level;
|
|
else
|
|
__default_logger_root.level = level;
|
|
}
|
|
|
|
void log_set_handler(logger_t *logger, log_handler handler) {
|
|
if (logger)
|
|
logger->handler = handler;
|
|
else
|
|
__default_logger_root.handler = handler;
|
|
}
|