stage1 重构代码

This commit is contained in:
zzy
2026-08-01 21:15:47 +08:00
parent a77eade06f
commit b43042c88d
30 changed files with 1211 additions and 6502 deletions

61
stage0/include/color.h Normal file
View File

@@ -0,0 +1,61 @@
/**
* @file color.h
* @brief ANSI终端颜色控制码定义
*
* 提供跨平台的终端文本颜色和样式控制支持
*/
#ifndef __SCC_TERMINAL_COLOR_H__
#define __SCC_TERMINAL_COLOR_H__
/* clang-format off */
/// @name 前景色控制码
/// @{
#define ANSI_FG_BLACK "\33[30m" ///< 黑色前景
#define ANSI_FG_RED "\33[31m" ///< 红色前景
#define ANSI_FG_GREEN "\33[32m" ///< 绿色前景
#define ANSI_FG_YELLOW "\33[33m" ///< 黄色前景
#define ANSI_FG_BLUE "\33[34m" ///< 蓝色前景
#define ANSI_FG_MAGENTA "\33[35m" ///< 品红色前景
#define ANSI_FG_CYAN "\33[36m" ///< 青色前景
#define ANSI_FG_WHITE "\33[37m" ///< 白色前景
/// @}
/// @name 背景色控制码
/// @{
#define ANSI_BG_BLACK "\33[40m" ///< 黑色背景
#define ANSI_BG_RED "\33[41m" ///< 红色背景
#define ANSI_BG_GREEN "\33[42m" ///< 绿色背景
#define ANSI_BG_YELLOW "\33[43m" ///< 黄色背景
#define ANSI_BG_BLUE "\33[44m" ///< 蓝色背景
#define ANSI_BG_MAGENTA "\33[45m" ///< 品红色背景原始代码此处应为45m
#define ANSI_BG_CYAN "\33[46m" ///< 青色背景
#define ANSI_BG_WHITE "\33[47m" ///< 白色背景
/// @}
/// @name 文字样式控制码
/// @{
#define ANSI_UNDERLINED "\33[4m" ///< 下划线样式
#define ANSI_BOLD "\33[1m" ///< 粗体样式
#define ANSI_NONE "\33[0m" ///< 重置所有样式
/// @}
/* clang-format on */
/**
* @def ANSI_FMT
* @brief 安全文本格式化宏
* @param str 目标字符串
* @param fmt ANSI格式序列可组合多个样式
*
* @note 当定义ANSI_FMT_DISABLE时自动禁用颜色输出
* @code
* printf(ANSI_FMT("Warning!", ANSI_FG_YELLOW ANSI_BOLD));
* @endcode
*/
#ifndef ANSI_FMT_DISABLE
#define ANSI_FMT(str, fmt) fmt str ANSI_NONE ///< 启用样式包裹
#else
#define ANSI_FMT(str, fmt) str ///< 禁用样式输出
#endif
#endif /* __SCC_TERMINAL_COLOR_H__ */

View File

@@ -9,7 +9,8 @@
#ifndef nullptr
#define nullptr NULL
#endif
typedef size_t usize;
typedef uintptr_t usize;
typedef intptr_t isize;
#define MAP_TYPEOF __typeof__
@@ -26,150 +27,147 @@ typedef size_t usize;
#define MAP_CMP_INT(a, b) ((a) != (b))
static inline usize map_hash_str(const char *s) {
usize h = 5381;
while (*s)
h = ((h << 5) + h) + (unsigned char)*s++;
return h;
usize h = 5381;
while (*s)
h = ((h << 5) + h) + (unsigned char)*s++;
return h;
}
#define MAP_HASH_STR map_hash_str
#define MAP_CMP_STR strcmp
/* ---------- 数据结构宏 ---------- */
#define MAP_SLOT(key_t, val_t) \
struct { \
key_t key; \
val_t val; \
char state; \
}
#define MAP_SLOT(key_t, val_t) \
struct { \
key_t key; \
val_t val; \
char state; \
}
#define MAP(key_t, val_t) \
struct { \
usize size; \
usize cap; \
MAP_SLOT(key_t, val_t) * data; \
usize (*hash)(key_t); \
int (*cmp)(key_t, key_t); \
}
#define MAP(key_t, val_t) \
struct { \
usize size; \
usize cap; \
MAP_SLOT(key_t, val_t) * data; \
usize (*hash)(key_t); \
int (*cmp)(key_t, key_t); \
}
/* ---------- 操作宏 ---------- */
/** 初始化,必须提供哈希和比较函数 */
#define map_init(map, hash_fn, cmp_fn) \
do { \
(map).size = 0; \
(map).cap = 0; \
(map).data = nullptr; \
(map).hash = (hash_fn); \
(map).cmp = (cmp_fn); \
} while (0)
#define map_init(map, hash_fn, cmp_fn) \
do { \
(map).size = 0; \
(map).cap = 0; \
(map).data = nullptr; \
(map).hash = (hash_fn); \
(map).cmp = (cmp_fn); \
} while (0)
/** 释放内部数组 */
#define map_free(map) \
do { \
free((map).data); \
(map).data = nullptr; \
(map).size = (map).cap = 0; \
} while (0)
#define map_free(map) \
do { \
free((map).data); \
(map).data = nullptr; \
(map).size = (map).cap = 0; \
} while (0)
/** 遍历所有有效元素 */
#define map_for(map, idx) \
for (usize(idx) = 0; (idx) < (map).cap; ++(idx)) \
if ((map).data[(idx)].state == __MAP_SLOT_OCCUPIED)
#define map_for(map, idx) \
for (usize(idx) = 0; (idx) < (map).cap; ++(idx)) \
if ((map).data[(idx)].state == __MAP_SLOT_OCCUPIED)
/**
* 插入(若键已存在则更新值)
* 注意:扩容使用 realloc失败会 abort可自行修改错误处理
*/
#define map_put(map, _key, _val) \
do { \
/* 扩容 */ \
if ((map).cap == 0 || \
(map).size * 128 / (map).cap >= MAP_DEFAULT_LOAD_FACTOR) { \
usize new_cap = (map).cap == 0 ? 8 : (map).cap * 2; \
MAP_SLOT(MAP_TYPEOF((map).data->key), \
MAP_TYPEOF((map).data->val)) *new_data = \
calloc(new_cap, sizeof(*new_data)); \
if (!new_data) \
abort(); \
/* 重新插入旧元素 */ \
for (usize _i = 0; _i < (map).cap; ++_i) { \
if ((map).data[_i].state == __MAP_SLOT_OCCUPIED) { \
usize _h = (map).hash((map).data[_i].key) & (new_cap - 1); \
while (new_data[_h].state == __MAP_SLOT_OCCUPIED) \
_h = (_h + 1) & (new_cap - 1); \
new_data[_h].key = (map).data[_i].key; \
new_data[_h].val = (map).data[_i].val; \
new_data[_h].state = __MAP_SLOT_OCCUPIED; \
} \
} \
free((map).data); \
(map).data = (void *)new_data; \
(map).cap = new_cap; \
} \
/* 查找或插入 */ \
usize _mask = (map).cap - 1; \
usize _idx = (map).hash(_key) & _mask; \
usize _first_del = (usize) - 1; \
while ((map).data[_idx].state != __MAP_SLOT_EMPTY) { \
if ((map).data[_idx].state == __MAP_SLOT_OCCUPIED && \
(map).cmp((map).data[_idx].key, _key) == 0) { \
(map).data[_idx].val = _val; \
break; \
} \
if ((map).data[_idx].state == __MAP_SLOT_DELETED && \
_first_del == (usize) - 1) \
_first_del = _idx; \
_idx = (_idx + 1) & _mask; \
} \
if ((map).data[_idx].state == __MAP_SLOT_EMPTY) { \
usize _target = (_first_del != (usize) - 1) ? _first_del : _idx; \
(map).data[_target].key = _key; \
(map).data[_target].val = _val; \
(map).data[_target].state = __MAP_SLOT_OCCUPIED; \
++(map).size; \
} \
} while (0)
#define map_put(map, _key, _val) \
do { \
/* 扩容 */ \
if ((map).cap == 0 || (map).size * 128 / (map).cap >= MAP_DEFAULT_LOAD_FACTOR) { \
usize new_cap = (map).cap == 0 ? 8 : (map).cap * 2; \
MAP_SLOT(MAP_TYPEOF((map).data->key), MAP_TYPEOF((map).data->val)) *new_data = \
calloc(new_cap, sizeof(*new_data)); \
if (!new_data) \
abort(); \
/* 重新插入旧元素 */ \
for (usize _i = 0; _i < (map).cap; ++_i) { \
if ((map).data[_i].state == __MAP_SLOT_OCCUPIED) { \
usize _h = (map).hash((map).data[_i].key) & (new_cap - 1); \
while (new_data[_h].state == __MAP_SLOT_OCCUPIED) \
_h = (_h + 1) & (new_cap - 1); \
new_data[_h].key = (map).data[_i].key; \
new_data[_h].val = (map).data[_i].val; \
new_data[_h].state = __MAP_SLOT_OCCUPIED; \
} \
} \
free((map).data); \
(map).data = (void *)new_data; \
(map).cap = new_cap; \
} \
/* 查找或插入 */ \
usize _mask = (map).cap - 1; \
usize _idx = (map).hash(_key) & _mask; \
usize _first_del = (usize) - 1; \
while ((map).data[_idx].state != __MAP_SLOT_EMPTY) { \
if ((map).data[_idx].state == __MAP_SLOT_OCCUPIED && \
(map).cmp((map).data[_idx].key, _key) == 0) { \
(map).data[_idx].val = _val; \
break; \
} \
if ((map).data[_idx].state == __MAP_SLOT_DELETED && _first_del == (usize) - 1) \
_first_del = _idx; \
_idx = (_idx + 1) & _mask; \
} \
if ((map).data[_idx].state == __MAP_SLOT_EMPTY) { \
usize _target = (_first_del != (usize) - 1) ? _first_del : _idx; \
(map).data[_target].key = _key; \
(map).data[_target].val = _val; \
(map).data[_target].state = __MAP_SLOT_OCCUPIED; \
++(map).size; \
} \
} while (0)
/**
* 查询:若找到,*out_val 被赋值为对应值并返回 1否则返回 0
*/
#define map_get(map, _key, out_val) \
(({ \
int _found = 0; \
if ((map).cap > 0) { \
usize _mask = (map).cap - 1; \
usize _idx = (map).hash(_key) & _mask; \
while ((map).data[_idx].state != __MAP_SLOT_EMPTY) { \
if ((map).data[_idx].state == __MAP_SLOT_OCCUPIED && \
(map).cmp((map).data[_idx].key, _key) == 0) { \
*out_val = (map).data[_idx].val; \
_found = 1; \
break; \
} \
_idx = (_idx + 1) & _mask; \
} \
} \
_found; \
}))
#define map_get(map, _key, out_val) \
(({ \
int _found = 0; \
if ((map).cap > 0) { \
usize _mask = (map).cap - 1; \
usize _idx = (map).hash(_key) & _mask; \
while ((map).data[_idx].state != __MAP_SLOT_EMPTY) { \
if ((map).data[_idx].state == __MAP_SLOT_OCCUPIED && \
(map).cmp((map).data[_idx].key, _key) == 0) { \
*out_val = (map).data[_idx].val; \
_found = 1; \
break; \
} \
_idx = (_idx + 1) & _mask; \
} \
} \
_found; \
}))
/**
* 删除指定键
*/
#define map_del(map, _key) \
do { \
if ((map).cap == 0) \
break; \
usize _mask = (map).cap - 1; \
usize _idx = (map).hash(_key) & _mask; \
while ((map).data[_idx].state != __MAP_SLOT_EMPTY) { \
if ((map).data[_idx].state == __MAP_SLOT_OCCUPIED && \
(map).cmp((map).data[_idx].key, _key) == 0) { \
(map).data[_idx].state = __MAP_SLOT_DELETED; \
--(map).size; \
break; \
} \
_idx = (_idx + 1) & _mask; \
} \
} while (0)
#define map_del(map, _key) \
do { \
if ((map).cap == 0) \
break; \
usize _mask = (map).cap - 1; \
usize _idx = (map).hash(_key) & _mask; \
while ((map).data[_idx].state != __MAP_SLOT_EMPTY) { \
if ((map).data[_idx].state == __MAP_SLOT_OCCUPIED && \
(map).cmp((map).data[_idx].key, _key) == 0) { \
(map).data[_idx].state = __MAP_SLOT_DELETED; \
--(map).size; \
break; \
} \
_idx = (_idx + 1) & _mask; \
} \
} while (0)
#endif /* __CORE_MAP_H__ */

View File

@@ -18,6 +18,7 @@
#define __vec_free free
#define __vec_memcpy memcpy
#else
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
@@ -32,11 +33,11 @@ typedef size_t usize;
#ifndef LOG_FATAL
#include <stdio.h>
#define LOG_FATAL(...) \
do { \
printf(__VA_ARGS__); \
abort(); \
} while (0)
#define LOG_FATAL(...) \
do { \
printf(__VA_ARGS__); \
abort(); \
} while (0)
#endif
#ifndef Assert
@@ -61,12 +62,12 @@ typedef size_t usize;
* struct people { VEC(char) name; int age; VEC(struct people) children;
* };
*/
#define VEC(type) \
struct { \
usize size; \
usize cap; \
type *data; \
}
#define VEC(type) \
struct { \
usize size; \
usize cap; \
type *data; \
}
/** @defgroup vec_operations 动态数组操作宏 */
@@ -77,20 +78,20 @@ typedef size_t usize;
*
* @note 此宏不会分配内存,仅做零初始化
*/
#define vec_init(vec) \
do { \
(vec).size = 0, (vec).cap = 0, (vec).data = 0; \
} while (0)
#define vec_init(vec) \
do { \
(vec).size = 0, (vec).cap = 0, (vec).data = 0; \
} while (0)
#define vec_realloc(vec, new_cap) \
do { \
void *data = __vec_realloc((vec).data, new_cap * sizeof(*(vec).data)); \
if (!data) { \
LOG_FATAL("vector_push: realloc failed\n"); \
} \
(vec).cap = new_cap; \
(vec).data = data; \
} while (0)
#define vec_realloc(vec, new_cap) \
do { \
void *data = __vec_realloc((vec).data, new_cap * sizeof(*(vec).data)); \
if (!data) { \
LOG_FATAL("vector_push: realloc failed\n"); \
} \
(vec).cap = new_cap; \
(vec).data = data; \
} while (0)
#define vec_size(vec) ((vec).size)
#define vec_cap(vec) ((vec).cap)
@@ -105,15 +106,15 @@ typedef size_t usize;
* @note 当容量不足时自动扩容为2倍初始容量为4
* @warning 内存分配失败时会触发LOG_FATAL
*/
#define vec_push(vec, value) \
do { \
if ((vec).size >= (vec).cap) { \
usize cap = (vec).cap ? (vec).cap * 2 : 4; \
vec_realloc(vec, cap); \
} \
Assert((vec).data != nullptr); \
(vec).data[(vec).size++] = value; \
} while (0)
#define vec_push(vec, value) \
do { \
if ((vec).size >= (vec).cap) { \
usize cap = (vec).cap ? (vec).cap * 2 : 4; \
vec_realloc(vec, cap); \
} \
Assert((vec).data != nullptr); \
(vec).data[(vec).size++] = value; \
} while (0)
/**
* @def vec_pop(vec)
@@ -149,43 +150,43 @@ typedef size_t usize;
*
* @note 释放后需重新初始化才能再次使用
*/
#define vec_free(vec) \
do { \
if ((vec).data == nullptr) \
break; \
__vec_free((vec).data); \
(vec).data = nullptr; \
(vec).size = (vec).cap = 0; \
} while (0)
#define vec_free(vec) \
do { \
if ((vec).data == nullptr) \
break; \
__vec_free((vec).data); \
(vec).data = nullptr; \
(vec).size = (vec).cap = 0; \
} while (0)
#define vec_unsafe_get_data(vec) ((vec).data)
#define vec_unsafe_from_buffer(vec, buffer, buffer_size) \
do { \
(vec).size = buffer_size; \
(vec).cap = (vec).size; \
(vec).data = buffer; \
} while (0)
#define vec_unsafe_from_buffer(vec, buffer, buffer_size) \
do { \
(vec).size = buffer_size; \
(vec).cap = (vec).size; \
(vec).data = buffer; \
} while (0)
#define vec_unsafe_from_static_array(vec, array) \
do { \
(vec).size = sizeof(array) / sizeof((array)[0]); \
(vec).cap = (vec).size; \
(vec).data = array; \
} while (0)
#define vec_unsafe_from_static_array(vec, array) \
do { \
(vec).size = sizeof(array) / sizeof((array)[0]); \
(vec).cap = (vec).size; \
(vec).data = array; \
} while (0)
/**
* @def vec_sized_realloc(vec, elem_size, new_cap)
* @brief 内部宏:按 elem_size 重新分配内存
*/
#define vec_sized_realloc(vec, elem_size, new_cap) \
do { \
void *new_data = __vec_realloc((vec).data, (new_cap) * (elem_size)); \
if (!new_data) \
LOG_FATAL("vec_sized_realloc: failed\n"); \
(vec).data = new_data; \
(vec).cap = new_cap; \
} while (0)
#define vec_sized_realloc(vec, elem_size, new_cap) \
do { \
void *new_data = __vec_realloc((vec).data, (new_cap) * (elem_size)); \
if (!new_data) \
LOG_FATAL("vec_sized_realloc: failed\n"); \
(vec).data = new_data; \
(vec).cap = new_cap; \
} while (0)
/**
* @def vec_sized_push(vec, elem_size, src_ptr)
@@ -198,24 +199,23 @@ typedef size_t usize;
* @note 使用前需确保 vec.data 类型与 src_ptr 无关,内部会按字节拷贝。
* 推荐声明时为 `VEC(char)` 或 `VEC(unsigned char)`。
*/
#define vec_sized_push(vec, elem_size, src_ptr, copy_size) \
do { \
if ((vec).size >= (vec).cap) { \
usize new_cap = (vec).cap ? (vec).cap * 2 : 4; \
vec_sized_realloc(vec, elem_size, new_cap); \
} \
char *slot = (char *)(vec).data + (vec).size * (elem_size); \
__vec_memcpy(slot, (src_ptr), (copy_size)); \
(vec).size++; \
} while (0)
#define vec_sized_push(vec, elem_size, src_ptr, copy_size) \
do { \
if ((vec).size >= (vec).cap) { \
usize new_cap = (vec).cap ? (vec).cap * 2 : 4; \
vec_sized_realloc(vec, elem_size, new_cap); \
} \
char *slot = (char *)(vec).data + (vec).size * (elem_size); \
__vec_memcpy(slot, (src_ptr), (copy_size)); \
(vec).size++; \
} while (0)
/**
* @def vec_sized_at_ptr(vec, elem_size, idx)
* @brief 获取第 idx 个元素的指针void*
* @return 指向元素的指针,需转换为具体类型使用
*/
#define vec_sized_at_ptr(vec, elem_size, idx) \
((void *)((char *)(vec).data + (idx) * (elem_size)))
#define vec_sized_at_ptr(vec, elem_size, idx) ((void *)((char *)(vec).data + (idx) * (elem_size)))
/**
* @def vec_sized_foreach(vec, elem_size, elem_ptr_var, block)
@@ -223,24 +223,24 @@ typedef size_t usize;
* @param elem_ptr_var 循环内的变量名void* 类型)
* @param block 循环体语句块
*/
#define vec_sized_foreach(vec, elem_size, elem_ptr_var, block) \
do { \
for (usize __i = 0; __i < (vec).size; ++__i) { \
void *elem_ptr_var = vec_sized_at_ptr(vec, elem_size, __i); \
block; \
} \
} while (0)
#define vec_sized_foreach(vec, elem_size, elem_ptr_var, block) \
do { \
for (usize __i = 0; __i < (vec).size; ++__i) { \
void *elem_ptr_var = vec_sized_at_ptr(vec, elem_size, __i); \
block; \
} \
} while (0)
/**
* @def vec_sized_pop(vec, elem_size)
* @brief 弹出最后一个元素(仅减小 size不返回数据
*/
#define vec_sized_pop(vec, elem_size) \
do { \
if ((vec).size == 0) \
LOG_FATAL("vec_sized_pop: empty\n"); \
(vec).size--; \
} while (0)
#define vec_sized_pop(vec, elem_size) \
do { \
if ((vec).size == 0) \
LOG_FATAL("vec_sized_pop: empty\n"); \
(vec).size--; \
} while (0)
/**
* @def vec_sized_clear(vec)

88
stage0/include/log.c Normal file
View File

@@ -0,0 +1,88 @@
#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);
// 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;
}

193
stage0/include/log.h Normal file
View File

@@ -0,0 +1,193 @@
/**
* @file log.h
* @brief 日志系统核心模块(支持多级日志、断言和异常处理)
*/
#ifndef __SCC_LOG_IMPL_H__
#define __SCC_LOG_IMPL_H__
#include "color.h"
#include <stdarg.h>
#ifdef __SCC_LOG_IMPL_USE_STD_IMPL__
#include <stdio.h>
#include <stdlib.h>
#define log_vsnprintf vsnprintf
#define log_puts puts
#define log_abort abort
#endif
#ifdef __GNUC__ // GCC, Clang
#define __scc_log_unreachable() (__builtin_unreachable())
#elif defined _MSC_VER // MSVC
#define __scc_log_unreachable() (__assume(false))
#elif defined __SCC_BUILTIN_UNREACHEABLE__ // The SCC Compiler (my compiler)
#define __scc_log_unreachable() (__scc_builtin_unreachable())
#else
#define __scc_log_unreachable() ((void)0)
#endif
#ifndef log_vsnprintf
#define log_vsnprintf(...)
#warning "log_vsnprintf not defined"
#endif
#ifndef log_puts
#define log_puts(...)
#warning "log_puts not defined"
#endif
#ifndef log_abort
#define log_abort(...)
#warning "log_abort not defined"
#endif
/**
* @brief 日志级别枚举
*
* 定义日志系统的输出级别和组合标志位
*/
typedef enum log_level {
LOG_LEVEL_NOTSET = 0, ///< 未设置级别(继承默认配置)
LOG_LEVEL_DEBUG = 1 << 0, ///< 调试信息(开发阶段详细信息)
LOG_LEVEL_INFO = 1 << 1, ///< 常规信息(系统运行状态)
LOG_LEVEL_WARN = 1 << 2, ///< 警告信息(潜在问题提示)
LOG_LEVEL_ERROR = 1 << 3, ///< 错误信息(可恢复的错误)
LOG_LEVEL_FATAL = 1 << 4, ///< 致命错误(导致程序终止的严重错误)
LOG_LEVEL_TRACE = 1 << 5, ///< 追踪(性能追踪或者栈帧追踪)
LOG_LEVEL_ALL = 0xFF, ///< 全级别标志(组合所有日志级别)
} log_level_t;
#ifndef LOGGER_MAX_BUF_SIZE
#define LOGGER_MAX_BUF_SIZE 512 ///< 单条日志最大缓冲区尺寸
#endif
typedef struct logger logger_t;
typedef int (*log_handler)(logger_t *module, log_level_t level, const char *file, int line,
const char *func, const char *fmt, ...);
/**
* @brief 日志器实例结构体
*
* 每个日志器实例维护独立的配置和缓冲区
*/
struct logger {
const char *name; ///< 日志器名称(用于模块区分)
log_level_t level; ///< 当前设置的日志级别
union {
log_handler handler;
void *user_handler;
}; ///< 日志处理回调函数
void *user_data; ///< 用户自定义数据
char buf[LOGGER_MAX_BUF_SIZE]; ///< 格式化缓冲区
};
int log_default_handler(logger_t *module, log_level_t level, const char *file, int line,
const char *func, const char *fmt, ...);
extern logger_t __default_logger_root;
#ifndef LOG_DEFAULT_HANDLER
#define LOG_DEFAULT_HANDLER &__default_logger_root
#endif
/**
* @brief 初始化日志实例 其余参数设置为默认值
* @param[in] logger 日志器实例指针
* @param[in] name 日志器名称nullptr表示获取默认日志器名称
*/
void init_logger(logger_t *logger, const char *name);
/**
* @brief 设置日志级别
* @param[in] logger 目标日志器实例
* @param[in] level 要设置的日志级别(可组合多个级别)
*/
void log_set_level(logger_t *logger, int level);
/**
* @brief 设置自定义日志处理器
* @param[in] logger 目标日志器实例
* @param[in] handler 自定义处理函数nullptr恢复默认处理
*/
void log_set_handler(logger_t *logger, log_handler handler);
#ifndef LOG_MAX_MAROC_BUF_SIZE
#define LOG_MAX_MAROC_BUF_SIZE LOGGER_MAX_BUF_SIZE ///< 宏展开缓冲区尺寸
#endif
#define SCC_LOG_HANDLE_ARGS(_module_, _level_, ...) \
(_module_), (_level_), __FILE__, __LINE__, __func__, ##__VA_ARGS__
#define SCC_LOG_IMPL(_module_, _level_, _fmt_, ...) \
do { \
/* TODO check _module_ is nullptr */ \
if ((_module_)->handler && ((_module_)->level & (_level_))) \
(_module_)->handler(SCC_LOG_HANDLE_ARGS(_module_, _level_, _fmt_, ##__VA_ARGS__)); \
} while (0)
/* clang-format off */
/// @name 模块日志宏
/// @{
#define MLOG_NOTSET(module, ...)SCC_LOG_IMPL(module, LOG_LEVEL_NOTSET, __VA_ARGS__) ///< 未分类日志
#define MLOG_DEBUG(module, ...) SCC_LOG_IMPL(module, LOG_LEVEL_DEBUG, __VA_ARGS__) ///< 调试日志需启用DEBUG级别
#define MLOG_INFO(module, ...) SCC_LOG_IMPL(module, LOG_LEVEL_INFO, __VA_ARGS__) ///< 信息日志(常规运行日志)
#define MLOG_WARN(module, ...) SCC_LOG_IMPL(module, LOG_LEVEL_WARN, __VA_ARGS__) ///< 警告日志(潜在问题)
#define MLOG_ERROR(module, ...) SCC_LOG_IMPL(module, LOG_LEVEL_ERROR, __VA_ARGS__) ///< 错误日志(可恢复错误)
#define MLOG_FATAL(module, ...) SCC_LOG_IMPL(module, LOG_LEVEL_FATAL, __VA_ARGS__) ///< 致命错误日志(程序终止前)
#define MLOG_TRACE(module, ...) SCC_LOG_IMPL(module, LOG_LEVEL_TRACE, __VA_ARGS__) ///< 追踪日志(调用栈跟踪)
/// @}
/// @name 快捷日志宏
/// @{
#define LOG_NOTSET(...) SCC_LOG_IMPL(LOG_DEFAULT_HANDLER, LOG_LEVEL_NOTSET, __VA_ARGS__) ///< 未分类日志
#define LOG_DEBUG(...) SCC_LOG_IMPL(LOG_DEFAULT_HANDLER, LOG_LEVEL_DEBUG, __VA_ARGS__) ///< 调试日志需启用DEBUG级别
#define LOG_INFO(...) SCC_LOG_IMPL(LOG_DEFAULT_HANDLER, LOG_LEVEL_INFO, __VA_ARGS__) ///< 信息日志(常规运行日志)
#define LOG_WARN(...) SCC_LOG_IMPL(LOG_DEFAULT_HANDLER, LOG_LEVEL_WARN, __VA_ARGS__) ///< 警告日志(潜在问题)
#define LOG_ERROR(...) SCC_LOG_IMPL(LOG_DEFAULT_HANDLER, LOG_LEVEL_ERROR, __VA_ARGS__) ///< 错误日志(可恢复错误)
#define LOG_FATAL(...) SCC_LOG_IMPL(LOG_DEFAULT_HANDLER, LOG_LEVEL_FATAL, __VA_ARGS__) ///< 致命错误日志(程序终止前)
#define LOG_TRACE(...) SCC_LOG_IMPL(LOG_DEFAULT_HANDLER, LOG_LEVEL_TRACE, __VA_ARGS__) ///< 追踪日志(调用栈跟踪)
/// @}
/* clang-format on */
/**
* @def _Assert
* @brief 断言检查内部宏
* @param cond 检查条件表达式
* @param ... 错误信息参数(格式字符串+参数)
*/
#define _Assert(cond, ...) \
((void)((cond) || (__default_logger_root.handler(SCC_LOG_HANDLE_ARGS( \
&__default_logger_root, LOG_LEVEL_FATAL, __VA_ARGS__)), \
log_abort(), __scc_log_unreachable(), 0)))
/// @name 断言工具宏
/// @{
#define __INNERSCC_LOG_IMPL_STR(str) #str
#define _SCC_LOG_IMPL_STR(str) __INNERSCC_LOG_IMPL_STR(str)
#define AssertFmt(cond, format, ...) \
_Assert(cond, "Assertion Failure: " format, ##__VA_ARGS__) ///< 带格式的断言检查
#define PanicFmt(format, ...) _Assert(0, "Panic: " format, ##__VA_ARGS__) ///< 立即触发致命错误
#define Assert(cond) AssertFmt(cond, "cond is `" _SCC_LOG_IMPL_STR(cond) "`") ///< 基础断言检查
#define Panic(...) PanicFmt(__VA_ARGS__) ///< 触发致命错误(带自定义消息)
#define TODO() PanicFmt("TODO please implement me") ///< 标记未实现代码(触发致命错误)
#define UNREACHABLE() PanicFmt("UNREACHABLE") ///< 触发致命错误(代码不可达)
#define FIXME(str) PanicFmt("FIXME " _SCC_LOG_IMPL_STR(str)) ///< 提醒开发者修改代码(触发致命错误)
/// @}
/**
* @brief 静态断言(编译时)
*
* 利用数组大小不能为负的特性
* 或使用 _Static_assert (C11)
*/
#if __STDC_VERSION__ >= 201112L
#define StaticAssert _Static_assert
#else
#define StaticAssert(cond, msg) extern char __static_assertion[(cond) ? 1 : -1]
#endif
#ifdef __SCC_LOG_IMPL_IMPORT_SRC__
#include "log.c"
#endif
#endif /* __SCC_LOG_IMPL_H__ */

10
stage0/include/utils.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef __UTILS_H__
#define __UTILS_H__
#define __SCC_LOG_IMPL_USE_STD_IMPL__
#include "log.h"
#include "core_map.h"
#include "core_vec.h"
#endif /* __UTILS_H__ */

View File

@@ -370,49 +370,6 @@ int spl_prog_add_data(spl_prog_t *prog, void *ptr, usize size) {
return vec_size(prog->gdata);
}
spl_val_t spl_prog_emit(spl_prog_t *prog, uint16_t opcode, uint16_t type, spl_val_t imm) {
spl_ins_t ins = {opcode, type, imm};
spl_val_t addr = vec_size(prog->insns);
vec_push(prog->insns, ins);
return addr;
}
int spl_prog_add_func_simple(spl_prog_t *prog, const char *name, spl_val_t nargs) {
spl_func_t func = {0};
if (!prog || !name)
return -1;
func.name = strdup(name);
func.idx_of_strtab = 0;
func.nargs = nargs;
func.ninsns = 0;
func.address = vec_size(prog->insns);
vec_push(prog->funcs, func);
return (int)vec_size(prog->funcs) - 1;
}
int spl_prog_update_func(spl_prog_t *prog, int func_idx, const char *name, spl_val_t nargs) {
if (!prog || func_idx < 0 || func_idx >= (int)vec_size(prog->funcs))
return spl_prog_add_func_simple(prog, name, nargs);
spl_func_t *func = &vec_at(prog->funcs, func_idx);
func->address = vec_size(prog->insns);
func->nargs = nargs;
return func_idx;
}
void spl_prog_end_func(spl_prog_t *prog, int func_idx) {
if (!prog || func_idx < 0 || func_idx >= (int)vec_size(prog->funcs))
return;
spl_func_t *func = &vec_at(prog->funcs, func_idx);
func->ninsns = vec_size(prog->insns) - func->address;
}
int spl_prog_add_str(spl_prog_t *prog, const char *str) {
if (!prog || !str)
return -1;
vec_push(prog->strtab, strdup(str));
return (int)vec_size(prog->strtab) - 1;
}
spl_func_t *spl_prog_get_func(spl_prog_t *prog, const char *name) {
if (!prog || !name)
return NULL;
@@ -445,10 +402,14 @@ const char *opcode_name[] = {
const char *spl_opcode_name(spl_opcode_t opcode) { return opcode_name[opcode]; }
const char *spl_type_tag_name(spl_type_t type) {
switch (type) {
case SPL_VOID: return "void";
case SPL_BOOL: return "bool";
case SPL_I8: return "i8";
case SPL_U8: return "u8";
case SPL_VOID:
return "void";
case SPL_BOOL:
return "bool";
case SPL_I8:
return "i8";
case SPL_U8:
return "u8";
case SPL_I16:
return "i16";
case SPL_U16:

View File

@@ -208,13 +208,6 @@ int spl_prog_add_native(spl_prog_t *prog, spl_native_t *native);
spl_func_t *spl_prog_get_func(spl_prog_t *prog, const char *name);
spl_native_t *spl_prog_get_native(spl_prog_t *prog, const char *name);
/* High-level program construction helpers */
spl_val_t spl_prog_emit(spl_prog_t *prog, uint16_t opcode, uint16_t type, spl_val_t imm);
int spl_prog_add_func_simple(spl_prog_t *prog, const char *name, spl_val_t nargs);
int spl_prog_update_func(spl_prog_t *prog, int func_idx, const char *name, spl_val_t nargs);
void spl_prog_end_func(spl_prog_t *prog, int func_idx);
int spl_prog_add_str(spl_prog_t *prog, const char *str);
/* Opcode name lookup for debugging/dumping */
const char *spl_opcode_name(spl_opcode_t opcode);
const char *spl_type_tag_name(spl_type_t type);

View File

@@ -5,7 +5,7 @@
*/
#include "include/acutest.h"
#include "spl_ir.h"
#include "spl_mcode.h"
#include "spl_vm.h"
#include <stdio.h>
@@ -13,7 +13,7 @@
#include <string.h>
/* ================================================================
* Binary-writing helpers (mirrors spl_ir.c internal format)
* Binary-writing helpers (mirrors spl_mcode.c internal format)
* ================================================================ */
/* Write spl_val_t (8 LE bytes), advance pointer */