From d1fafa830d8c3b94e97f67f14a1fd9fd1de424cb Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Thu, 20 Nov 2025 17:55:08 +0800 Subject: [PATCH] format using clang-format to formate code --- libs/lexer/include/lexer.h | 16 +- libs/lexer/include/lexer_log.h | 24 +- libs/lexer/include/lexer_token.h | 36 +-- libs/lexer/src/lexer.c | 402 ++++++++++++++++---------- libs/lexer/tests/test_number.c | 4 +- libs/lexer/tests/test_run.c | 20 +- runtime/libcore/include/core_impl.h | 14 +- runtime/libcore/include/core_log.h | 7 +- runtime/libcore/include/core_mem.h | 12 +- runtime/libcore/include/core_str.h | 84 +++--- runtime/libcore/include/core_stream.h | 29 +- runtime/libcore/include/core_type.h | 12 +- runtime/libcore/include/core_vec.h | 115 ++++++++ runtime/libcore/include/libcore.h | 9 +- runtime/libcore/src/cfg.std_impl.c | 59 ++-- runtime/libcore/src/memory.c | 326 ++++++++++++++------- runtime/libcore/src/stream.c | 36 +-- runtime/libutils/include/hashtable.h | 45 +-- runtime/libutils/include/kllist.h | 68 +++-- runtime/libutils/include/libutils.h | 7 +- runtime/libutils/include/strpool.h | 18 +- runtime/libutils/include/vector.h | 119 -------- runtime/libutils/src/hashtable.c | 82 +++--- runtime/libutils/src/strpool.c | 18 +- runtime/log/include/color.h | 10 +- runtime/log/include/log.c | 95 +++--- runtime/log/include/log.h | 146 ++++++---- 27 files changed, 1047 insertions(+), 766 deletions(-) create mode 100644 runtime/libcore/include/core_vec.h delete mode 100644 runtime/libutils/include/vector.h diff --git a/libs/lexer/include/lexer.h b/libs/lexer/include/lexer.h index 973a195..ca71453 100644 --- a/libs/lexer/include/lexer.h +++ b/libs/lexer/include/lexer.h @@ -6,8 +6,8 @@ #ifndef __SMCC_CC_LEXER_H__ #define __SMCC_CC_LEXER_H__ -#include #include "lexer_token.h" +#include typedef struct lexer_loc { const char *name; @@ -25,11 +25,11 @@ typedef struct lexer_token { /** * @brief 词法分析器核心结构体 - * + * * 封装词法分析所需的状态信息和缓冲区管理 */ typedef struct cc_lexer { - core_stream_t* stream; + core_stream_t *stream; lexer_loc_t pos; } smcc_lexer_t; @@ -38,24 +38,24 @@ typedef struct cc_lexer { * @param[out] lexer 要初始化的词法分析器实例 * @param[in] stream 输入流对象指针 */ -void lexer_init(smcc_lexer_t* lexer, core_stream_t* stream); +void lexer_init(smcc_lexer_t *lexer, core_stream_t *stream); /** * @brief 获取原始token * @param[in] lexer 词法分析器实例 * @param[out] token 输出token存储位置 - * + * * 此函数会返回所有类型的token,包括空白符等无效token */ -void lexer_get_token(smcc_lexer_t* lexer, lexer_tok_t* token); +void lexer_get_token(smcc_lexer_t *lexer, lexer_tok_t *token); /** * @brief 获取有效token * @param[in] lexer 词法分析器实例 * @param[out] token 输出token存储位置 - * + * * 此函数会自动跳过空白符等无效token,返回对语法分析有意义的token */ -void lexer_get_valid_token(smcc_lexer_t* lexer, lexer_tok_t* token); +void lexer_get_valid_token(smcc_lexer_t *lexer, lexer_tok_t *token); #endif diff --git a/libs/lexer/include/lexer_log.h b/libs/lexer/include/lexer_log.h index 493dbec..c1cc4c6 100644 --- a/libs/lexer/include/lexer_log.h +++ b/libs/lexer/include/lexer_log.h @@ -8,39 +8,39 @@ #endif #if LEX_LOG_LEVEL <= 1 -#define LEX_NOTSET( fmt, ...) MLOG_NOTSET(&__smcc_lexer_log, fmt, ##__VA_ARGS__) +#define LEX_NOTSET(fmt, ...) MLOG_NOTSET(&__smcc_lexer_log, fmt, ##__VA_ARGS__) #else -#define LEX_NOTSET( fmt, ...) +#define LEX_NOTSET(fmt, ...) #endif #if LEX_LOG_LEVEL <= 2 -#define LEX_DEBUG( fmt, ...) MLOG_DEBUG(&__smcc_lexer_log, fmt, ##__VA_ARGS__) +#define LEX_DEBUG(fmt, ...) MLOG_DEBUG(&__smcc_lexer_log, fmt, ##__VA_ARGS__) #else -#define LEX_DEBUG( fmt, ...) +#define LEX_DEBUG(fmt, ...) #endif #if LEX_LOG_LEVEL <= 3 -#define LEX_INFO( fmt, ...) MLOG_INFO(&__smcc_lexer_log, fmt, ##__VA_ARGS__) +#define LEX_INFO(fmt, ...) MLOG_INFO(&__smcc_lexer_log, fmt, ##__VA_ARGS__) #else -#define LEX_INFO( fmt, ...) +#define LEX_INFO(fmt, ...) #endif #if LEX_LOG_LEVEL <= 4 -#define LEX_WARN( fmt, ...) MLOG_WARN(&__smcc_lexer_log, fmt, ##__VA_ARGS__) +#define LEX_WARN(fmt, ...) MLOG_WARN(&__smcc_lexer_log, fmt, ##__VA_ARGS__) #else -#define LEX_WARN( fmt, ...) +#define LEX_WARN(fmt, ...) #endif #if LEX_LOG_LEVEL <= 5 -#define LEX_ERROR( fmt, ...) MLOG_ERROR(&__smcc_lexer_log, fmt, ##__VA_ARGS__) +#define LEX_ERROR(fmt, ...) MLOG_ERROR(&__smcc_lexer_log, fmt, ##__VA_ARGS__) #else -#define LEX_ERROR( fmt, ...) +#define LEX_ERROR(fmt, ...) #endif #if LEX_LOG_LEVEL <= 6 -#define LEX_FATAL( fmt, ...) MLOG_FATAL(&__smcc_lexer_log, fmt, ##__VA_ARGS__) +#define LEX_FATAL(fmt, ...) MLOG_FATAL(&__smcc_lexer_log, fmt, ##__VA_ARGS__) #else -#define LEX_FATAL( fmt, ...) +#define LEX_FATAL(fmt, ...) #endif extern logger_t __smcc_lexer_log; diff --git a/libs/lexer/include/lexer_token.h b/libs/lexer/include/lexer_token.h index 59ccc55..14349b4 100644 --- a/libs/lexer/include/lexer_token.h +++ b/libs/lexer/include/lexer_token.h @@ -10,6 +10,7 @@ typedef enum ckeyword { } ckeyword_t; // Using Binary Search To Fast Find Keyword +/* clang-format off */ #define KEYWORD_TABLE \ X(asm , TK_BASIC_KEYWORD , TOKEN_ASM , CEXT_ASM) \ X(break , TK_BASIC_KEYWORD , TOKEN_BREAK , CSTD_C89) \ @@ -105,33 +106,34 @@ typedef enum ckeyword { X(char_literal , TK_BASIC_LITERAL, TOKEN_CHAR_LITERAL ) \ X(string_literal , TK_BASIC_LITERAL, TOKEN_STRING_LITERAL ) \ // END +/* clang-format on */ // 定义TokenType枚举 typedef enum cc_tktype { - // 处理普通token - #define X(str, subtype, tok) tok, +// 处理普通token +#define X(str, subtype, tok) tok, TOKEN_TABLE - #undef X - - // 处理关键字(保持原有格式) - #define X(name, subtype, tok, std) tok, - KEYWORD_TABLE - #undef X +#undef X + +// 处理关键字(保持原有格式) +#define X(name, subtype, tok, std) tok, + KEYWORD_TABLE +#undef X } token_type_t; typedef enum token_subtype { - TK_BASIC_INVALID, // 错误占位 - TK_BASIC_KEYWORD, // 关键字 - TK_BASIC_OPERATOR, // 操作符 - TK_BASIC_IDENTIFIER, // 标识符 - TK_BASIC_LITERAL, // 字面量 + TK_BASIC_INVALID, // 错误占位 + TK_BASIC_KEYWORD, // 关键字 + TK_BASIC_OPERATOR, // 操作符 + TK_BASIC_IDENTIFIER, // 标识符 + TK_BASIC_LITERAL, // 字面量 - TK_BASIC_EMPTYSPACE, // 空白 - TK_BASIC_COMMENT, // 注释 - TK_BASIC_EOF // 结束标记 + TK_BASIC_EMPTYSPACE, // 空白 + TK_BASIC_COMMENT, // 注释 + TK_BASIC_EOF // 结束标记 } token_subtype_t; token_subtype_t get_tok_subtype(token_type_t type); -const char* get_tok_name(token_type_t type); +const char *get_tok_name(token_type_t type); #endif diff --git a/libs/lexer/src/lexer.c b/libs/lexer/src/lexer.c index 4a1d43c..a27f587 100644 --- a/libs/lexer/src/lexer.c +++ b/libs/lexer/src/lexer.c @@ -1,6 +1,6 @@ /** * 仿照LCCompiler的词法分析部分 - * + * * 如下为LCC的README in 2025.2 This hierarchy is the distribution for lcc version 4.2. @@ -26,43 +26,45 @@ the distribution and installation instructions. Chris Fraser / cwf@aya.yale.edu David Hanson / drh@drhanson.net */ -#include #include +#include static const struct { - const char* name; + const char *name; ckeyword_t std_type; token_type_t tok; } keywords[] = { - #define X(name, subtype, tok, std_type,...) { #name, std_type, tok }, +#define X(name, subtype, tok, std_type, ...) {#name, std_type, tok}, KEYWORD_TABLE - #undef X +#undef X }; // by using binary search to find the keyword -static inline int keyword_cmp(const char* name, int len) { +static inline int keyword_cmp(const char *name, int len) { int low = 0; int high = sizeof(keywords) / sizeof(keywords[0]) - 1; while (low <= high) { int mid = (low + high) / 2; const char *key = keywords[mid].name; int cmp = 0; - + // 自定义字符串比较逻辑 for (int i = 0; i < len; i++) { if (name[i] != key[i]) { cmp = (unsigned char)name[i] - (unsigned char)key[i]; break; } - if (name[i] == '\0') break; // 遇到终止符提前结束 + if (name[i] == '\0') + break; // 遇到终止符提前结束 } - + if (cmp == 0) { // 完全匹配检查(长度相同) - if (key[len] == '\0') return mid; + if (key[len] == '\0') + return mid; cmp = -1; // 当前关键词比输入长 } - + if (cmp < 0) { high = mid - 1; } else { @@ -72,9 +74,9 @@ static inline int keyword_cmp(const char* name, int len) { return -1; // Not a keyword. } -void lexer_init(smcc_lexer_t* lexer, core_stream_t* stream) { +void lexer_init(smcc_lexer_t *lexer, core_stream_t *stream) { lexer->stream = stream; - lexer->pos = (lexer_loc_t) { + lexer->pos = (lexer_loc_t){ .name = cstring_as_cstr(&stream->name), .name_len = cstring_len(&stream->name), .line = 1, @@ -83,26 +85,26 @@ void lexer_init(smcc_lexer_t* lexer, core_stream_t* stream) { }; } -#define stream_reset_char(stream) ((stream)->reset_char(stream)) -#define stream_next_char(stream) ((stream)->next_char(stream)) -#define stream_peek_char(stream) ((stream)->peek_char(stream)) -#define lexer_next_pos(lexer) ((lexer)->pos.column ++, (lexer)->pos.offset ++) -#define lexer_next_line(lexer) ((lexer)->pos.line ++, (lexer)->pos.column = 1) -#define set_err_token(token) ((token)->type = TOKEN_UNKNOWN) +#define stream_reset_char(stream) ((stream)->reset_char(stream)) +#define stream_next_char(stream) ((stream)->next_char(stream)) +#define stream_peek_char(stream) ((stream)->peek_char(stream)) +#define lexer_next_pos(lexer) ((lexer)->pos.column++, (lexer)->pos.offset++) +#define lexer_next_line(lexer) ((lexer)->pos.line++, (lexer)->pos.column = 1) +#define set_err_token(token) ((token)->type = TOKEN_UNKNOWN) -static void skip_newline(smcc_lexer_t* lexer, lexer_tok_t* token) { - core_stream_t* stream = lexer->stream; +static void skip_newline(smcc_lexer_t *lexer, lexer_tok_t *token) { + core_stream_t *stream = lexer->stream; token->type = TOKEN_LINE_COMMENT; // 循环直到遇到换行符或文件结束 while (1) { int ch = stream_next_char(stream); - + if (ch == core_stream_eof) { // 到达文件末尾,直接返回 return; } - + // 更新位置信息 lexer_next_pos(lexer); if (ch == '\n') { @@ -113,19 +115,19 @@ static void skip_newline(smcc_lexer_t* lexer, lexer_tok_t* token) { } } -static void skip_block_comment(smcc_lexer_t* lexer, lexer_tok_t* token) { - core_stream_t* stream = lexer->stream; +static void skip_block_comment(smcc_lexer_t *lexer, lexer_tok_t *token) { + core_stream_t *stream = lexer->stream; token->type = TOKEN_BLOCK_COMMENT; int ch; - + stream_reset_char(stream); ch = stream_next_char(stream); lexer_next_pos(lexer); // FIXME Assertion - Assert (ch == '/'); + Assert(ch == '/'); ch = stream_next_char(stream); lexer_next_pos(lexer); - Assert (ch == '*'); + Assert(ch == '*'); // 我们已经识别了 "/*",现在需要找到 "*/" while (1) { ch = stream_next_char(stream); @@ -136,7 +138,7 @@ static void skip_block_comment(smcc_lexer_t* lexer, lexer_tok_t* token) { LEX_WARN("Unterminated block comment"); return; } - + // LEX_ERROR("%c", ch); // 更新位置信息 @@ -149,10 +151,10 @@ static void skip_block_comment(smcc_lexer_t* lexer, lexer_tok_t* token) { if (next_ch == '/') { // 消费 '/' 字符 stream_next_char(stream); - + // 更新位置信息 lexer_next_pos(lexer); - + // 成功找到注释结束标记 return; } @@ -163,24 +165,36 @@ static void skip_block_comment(smcc_lexer_t* lexer, lexer_tok_t* token) { // TODO escape character not enough static inline int got_slash(int peek) { switch (peek) { - case '\\': return '\\'; - case '\'': return '\''; - case '\"': return '\"'; - case '\?': return '\?'; - case '0': return '\0'; + case '\\': + return '\\'; + case '\'': + return '\''; + case '\"': + return '\"'; + case '\?': + return '\?'; + case '0': + return '\0'; - case 'b': return '\b'; - case 'f': return '\f'; - case 'n': return '\n'; - case 'r': return '\r'; - case 't': return '\t'; - case 'v': return '\v'; - default: break; + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case 'v': + return '\v'; + default: + break; } return -1; } -static void parse_char(smcc_lexer_t* lexer, lexer_tok_t* token) { +static void parse_char(smcc_lexer_t *lexer, lexer_tok_t *token) { token->loc = lexer->pos; token->type = TOKEN_CHAR_LITERAL; core_stream_t *stream = lexer->stream; @@ -226,7 +240,7 @@ ERR: set_err_token(token); } -static void parse_string(smcc_lexer_t* lexer, lexer_tok_t* token) { +static void parse_string(smcc_lexer_t *lexer, lexer_tok_t *token) { token->loc = lexer->pos; token->type = TOKEN_STRING_LITERAL; core_stream_t *stream = lexer->stream; @@ -242,12 +256,12 @@ static void parse_string(smcc_lexer_t* lexer, lexer_tok_t* token) { } stream_next_char(stream); lexer_next_pos(lexer); - + int base = 0; cstring_t str = cstring_new(); while (1) { ch = stream_peek_char(stream); - + if (ch == core_stream_eof) { LEX_ERROR("Unexpected EOF at string literal"); break; @@ -276,14 +290,14 @@ static void parse_string(smcc_lexer_t* lexer, lexer_tok_t* token) { cstring_push(&str, ch); } - token->value.cstr.data = (char*)cstring_as_cstr(&str); + token->value.cstr.data = (char *)cstring_as_cstr(&str); token->value.cstr.len = cstring_len(&str); return; ERR: set_err_token(token); } -static void parse_number(smcc_lexer_t* lexer, lexer_tok_t* token) { +static void parse_number(smcc_lexer_t *lexer, lexer_tok_t *token) { token->loc = lexer->pos; core_stream_t *stream = lexer->stream; stream_reset_char(stream); @@ -354,7 +368,7 @@ ERR: set_err_token(token); } -static void parse_line(smcc_lexer_t* lexer, lexer_tok_t* token) { +static void parse_line(smcc_lexer_t *lexer, lexer_tok_t *token) { token->loc = lexer->pos; core_stream_t *stream = lexer->stream; stream_reset_char(stream); @@ -374,7 +388,8 @@ static void parse_line(smcc_lexer_t* lexer, lexer_tok_t* token) { ch = stream_next_char(stream); lexer_next_pos(lexer); if (ch != line[i]) { - LEX_WARN("Maroc does not support in lexer rather in preprocessor, it will be ignored"); + LEX_WARN("Maroc does not support in lexer rather in preprocessor, " + "it will be ignored"); goto SKIP_LINE; } } @@ -414,7 +429,7 @@ ERR: } // /zh/c/language/operator_arithmetic.html -void lexer_get_token(smcc_lexer_t* lexer, lexer_tok_t* token) { +void lexer_get_token(smcc_lexer_t *lexer, lexer_tok_t *token) { token->loc = lexer->pos; token->type = TOKEN_UNKNOWN; core_stream_t *stream = lexer->stream; @@ -427,122 +442,213 @@ void lexer_get_token(smcc_lexer_t* lexer, lexer_tok_t* token) { switch (ch) { case '=': switch (stream_peek_char(stream)) { - case '=': type = TOKEN_EQ; goto double_char; - default: stream_reset_char(stream), type = TOKEN_ASSIGN; break; - } break; + case '=': + type = TOKEN_EQ; + goto double_char; + default: + stream_reset_char(stream), type = TOKEN_ASSIGN; + break; + } + break; case '+': switch (stream_peek_char(stream)) { - case '+': type = TOKEN_ADD_ADD; goto double_char; - case '=': type = TOKEN_ASSIGN_ADD; goto double_char; - default: stream_reset_char(stream), type = TOKEN_ADD; break; - } break; + case '+': + type = TOKEN_ADD_ADD; + goto double_char; + case '=': + type = TOKEN_ASSIGN_ADD; + goto double_char; + default: + stream_reset_char(stream), type = TOKEN_ADD; + break; + } + break; case '-': switch (stream_peek_char(stream)) { - case '-': type = TOKEN_SUB_SUB; goto double_char; - case '=': type = TOKEN_ASSIGN_SUB; goto double_char; - case '>': type = TOKEN_DEREF; goto double_char; - default: stream_reset_char(stream), type = TOKEN_SUB; break; - } break; + case '-': + type = TOKEN_SUB_SUB; + goto double_char; + case '=': + type = TOKEN_ASSIGN_SUB; + goto double_char; + case '>': + type = TOKEN_DEREF; + goto double_char; + default: + stream_reset_char(stream), type = TOKEN_SUB; + break; + } + break; case '*': switch (stream_peek_char(stream)) { - case '=': type = TOKEN_ASSIGN_MUL; goto double_char; - default: stream_reset_char(stream), type = TOKEN_MUL; break; - } break; + case '=': + type = TOKEN_ASSIGN_MUL; + goto double_char; + default: + stream_reset_char(stream), type = TOKEN_MUL; + break; + } + break; case '/': switch (stream_peek_char(stream)) { - case '=': type = TOKEN_ASSIGN_DIV; goto double_char; - case '/': skip_newline(lexer, token); goto END; - case '*': skip_block_comment(lexer, token); goto END; - default: stream_reset_char(stream), type = TOKEN_DIV; break; - } break; + case '=': + type = TOKEN_ASSIGN_DIV; + goto double_char; + case '/': + skip_newline(lexer, token); + goto END; + case '*': + skip_block_comment(lexer, token); + goto END; + default: + stream_reset_char(stream), type = TOKEN_DIV; + break; + } + break; case '%': switch (stream_peek_char(stream)) { - case '=': type = TOKEN_ASSIGN_MOD; goto double_char; - default: stream_reset_char(stream), type = TOKEN_MOD; break; - } break; + case '=': + type = TOKEN_ASSIGN_MOD; + goto double_char; + default: + stream_reset_char(stream), type = TOKEN_MOD; + break; + } + break; case '&': switch (stream_peek_char(stream)) { - case '&': type = TOKEN_AND_AND; goto double_char; - case '=': type = TOKEN_ASSIGN_AND; goto double_char; - default: stream_reset_char(stream), type = TOKEN_AND; break; - } break; + case '&': + type = TOKEN_AND_AND; + goto double_char; + case '=': + type = TOKEN_ASSIGN_AND; + goto double_char; + default: + stream_reset_char(stream), type = TOKEN_AND; + break; + } + break; case '|': switch (stream_peek_char(stream)) { - case '|': type = TOKEN_OR_OR; goto double_char; - case '=': type = TOKEN_ASSIGN_OR; goto double_char; - default: stream_reset_char(stream), type = TOKEN_OR; break; - } break; + case '|': + type = TOKEN_OR_OR; + goto double_char; + case '=': + type = TOKEN_ASSIGN_OR; + goto double_char; + default: + stream_reset_char(stream), type = TOKEN_OR; + break; + } + break; case '^': switch (stream_peek_char(stream)) { - case '=': type = TOKEN_ASSIGN_XOR; goto double_char; - default: stream_reset_char(stream), type = TOKEN_XOR; break; - } break; + case '=': + type = TOKEN_ASSIGN_XOR; + goto double_char; + default: + stream_reset_char(stream), type = TOKEN_XOR; + break; + } + break; case '<': switch (stream_peek_char(stream)) { - case '=': type = TOKEN_LE; goto double_char; - case '<': { - if (stream_peek_char(stream) == '=') { - type = TOKEN_ASSIGN_L_SH; - goto triple_char; - } else { - type = TOKEN_L_SH; - goto double_char; - } - break; + case '=': + type = TOKEN_LE; + goto double_char; + case '<': { + if (stream_peek_char(stream) == '=') { + type = TOKEN_ASSIGN_L_SH; + goto triple_char; + } else { + type = TOKEN_L_SH; + goto double_char; } - default: stream_reset_char(stream), type = TOKEN_LT; break; - } break; + break; + } + default: + stream_reset_char(stream), type = TOKEN_LT; + break; + } + break; case '>': switch (stream_peek_char(stream)) { - case '=': type = TOKEN_GE; goto double_char; - case '>': { - if (stream_peek_char(stream) == '=') { - type = TOKEN_ASSIGN_R_SH; - goto triple_char; - } else { - type = TOKEN_R_SH; - goto double_char; - } - break; + case '=': + type = TOKEN_GE; + goto double_char; + case '>': { + if (stream_peek_char(stream) == '=') { + type = TOKEN_ASSIGN_R_SH; + goto triple_char; + } else { + type = TOKEN_R_SH; + goto double_char; } - default: stream_reset_char(stream), type = TOKEN_GT; break; - } break; + break; + } + default: + stream_reset_char(stream), type = TOKEN_GT; + break; + } + break; case '~': - type = TOKEN_BIT_NOT; break; + type = TOKEN_BIT_NOT; + break; case '!': switch (stream_peek_char(stream)) { - case '=': type = TOKEN_NEQ; goto double_char; - default: stream_reset_char(stream), type = TOKEN_NOT; break; - } break; + case '=': + type = TOKEN_NEQ; + goto double_char; + default: + stream_reset_char(stream), type = TOKEN_NOT; + break; + } + break; case '[': - type = TOKEN_L_BRACKET; break; + type = TOKEN_L_BRACKET; + break; case ']': - type = TOKEN_R_BRACKET; break; + type = TOKEN_R_BRACKET; + break; case '(': - type = TOKEN_L_PAREN; break; + type = TOKEN_L_PAREN; + break; case ')': - type = TOKEN_R_PAREN; break; + type = TOKEN_R_PAREN; + break; case '{': - type = TOKEN_L_BRACE; break; + type = TOKEN_L_BRACE; + break; case '}': - type = TOKEN_R_BRACE; break; + type = TOKEN_R_BRACE; + break; case ';': - type = TOKEN_SEMICOLON; break; + type = TOKEN_SEMICOLON; + break; case ',': - type = TOKEN_COMMA; break; + type = TOKEN_COMMA; + break; case ':': - type = TOKEN_COLON; break; + type = TOKEN_COLON; + break; case '.': - if (stream_peek_char(stream) == '.' && stream_peek_char(stream) == '.') { + if (stream_peek_char(stream) == '.' && + stream_peek_char(stream) == '.') { type = TOKEN_ELLIPSIS; goto triple_char; } - type = TOKEN_DOT; break; + type = TOKEN_DOT; + break; case '?': - type = TOKEN_COND; break; - case '\v': case '\r': case '\f': - case ' ': case '\t': - type = TOKEN_BLANK; break; + type = TOKEN_COND; + break; + case '\v': + case '\r': + case '\f': + case ' ': + case '\t': + type = TOKEN_BLANK; + break; case '\n': // you need to flush a newline or blank stream_next_char(stream); @@ -565,19 +671,22 @@ void lexer_get_token(smcc_lexer_t* lexer, lexer_tok_t* token) { case '"': parse_string(lexer, token); goto END; + /* clang-format off */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + /* clang-format on */ parse_number(lexer, token); goto END; - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': - case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': - case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': - case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': - case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':case 'Y': case 'Z': - case '_': + /* clang-format off */ + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': + case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': + case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': + case 'v': case 'w': case 'x': case 'y': case 'z': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': + case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': + case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': + case 'V': case 'W': case 'X': case 'Y': case 'Z': case '_': + /* clang-format on */ // TOKEN_IDENT // TODO // if ((ch == 'L' && ch == '\'') || (ch == 'L' && ch == '"')) { @@ -596,13 +705,15 @@ void lexer_get_token(smcc_lexer_t* lexer, lexer_tok_t* token) { break; } - int res = keyword_cmp((const char*)str.data, str.len); + int res = keyword_cmp((const char *)str.data, str.size - 1); if (res == -1) { - token->value.cstr.data = (char*)cstring_as_cstr(&str); + token->value.cstr.data = (char *)cstring_as_cstr(&str); token->value.cstr.len = cstring_len(&str); - type = TOKEN_IDENT; break; + type = TOKEN_IDENT; + break; } else { - type = keywords[res].tok; break; + type = keywords[res].tok; + break; } default: LEX_ERROR("unsupport char in sourse code `%c`", ch); @@ -621,16 +732,17 @@ once_char: token->type = type; END: LEX_DEBUG("get token `%s` in %s:%d:%d", get_tok_name(token->type), - token->loc.name, token->loc.line, token->loc.column); + token->loc.name, token->loc.line, token->loc.column); } // lexer_get_token maybe got invalid (with parser) -void lexer_get_valid_token(smcc_lexer_t* lexer, lexer_tok_t* token) { +void lexer_get_valid_token(smcc_lexer_t *lexer, lexer_tok_t *token) { token_subtype_t type; do { lexer_get_token(lexer, token); type = get_tok_subtype(token->type); AssertFmt(type != TK_BASIC_INVALID, "Invalid token: `%s` at %s:%d:%d", - get_tok_name(token->type), token->loc.name, token->loc.line, token->loc.column); + get_tok_name(token->type), token->loc.name, token->loc.line, + token->loc.column); } while (type == TK_BASIC_EMPTYSPACE || type == TK_BASIC_COMMENT); } diff --git a/libs/lexer/tests/test_number.c b/libs/lexer/tests/test_number.c index 815d771..afd7957 100644 --- a/libs/lexer/tests/test_number.c +++ b/libs/lexer/tests/test_number.c @@ -1,4 +1,2 @@ -int main() { - -} \ No newline at end of file +int main() {} \ No newline at end of file diff --git a/libs/lexer/tests/test_run.c b/libs/lexer/tests/test_run.c index a926298..92dbb99 100644 --- a/libs/lexer/tests/test_run.c +++ b/libs/lexer/tests/test_run.c @@ -1,7 +1,7 @@ #include +#include #include #include -#include #include /// gcc -g ../lexer.c ../token.c test_lexer.c -o test_lexer /* @@ -20,19 +20,17 @@ tok_tConstant { int g_num; int g_num_arr[3]; -int main(int argc, char* argv[]) { +int main(int argc, char *argv[]) { // int num = 0; if (argc == 3 && strcmp(argv[2], "-nodebug") == 0) { - log_set_level(NULL, LOG_LEVEL_INFO - | LOG_LEVEL_WARN - | LOG_LEVEL_ERROR); + log_set_level(NULL, LOG_LEVEL_INFO | LOG_LEVEL_WARN | LOG_LEVEL_ERROR); } - const char* file_name = __FILE__; + const char *file_name = __FILE__; if (argc == 2) { file_name = argv[1]; } - FILE* fp = fopen(file_name, "rb"); + FILE *fp = fopen(file_name, "rb"); if (fp == NULL) { perror("open file failed"); return 1; @@ -50,7 +48,7 @@ int main(int argc, char* argv[]) { return 1; } - char* buffer = (char*) malloc(fsize); + char *buffer = (char *)malloc(fsize); usize read_ret = fread(buffer, 1, fsize, fp); fclose(fp); @@ -62,7 +60,8 @@ int main(int argc, char* argv[]) { smcc_lexer_t lexer; core_mem_stream_t mem_stream = {0}; - core_stream_t* stream = core_mem_stream_init(&mem_stream, buffer, fsize, false); + core_stream_t *stream = + core_mem_stream_init(&mem_stream, buffer, fsize, false); Assert(stream != null); cstring_clear(&stream->name); cstring_push_cstr(&stream->name, file_name, strlen(file_name)); @@ -74,7 +73,8 @@ int main(int argc, char* argv[]) { if (tok.type == TOKEN_EOF) { break; } - LOG_DEBUG("token `%s` at %s:%u:%u", get_tok_name(tok.type), tok.loc.name, tok.loc.line, tok.loc.column); + LOG_DEBUG("token `%s` at %s:%u:%u", get_tok_name(tok.type), + tok.loc.name, tok.loc.line, tok.loc.column); Assert(tok.loc.offset <= fsize); // LOG_DEBUG("%s", tok.val.str); // printf("line: %d, column: %d, type: %3d, typename: %s\n", diff --git a/runtime/libcore/include/core_impl.h b/runtime/libcore/include/core_impl.h index e05c72c..e40be24 100644 --- a/runtime/libcore/include/core_impl.h +++ b/runtime/libcore/include/core_impl.h @@ -5,21 +5,21 @@ /* ====== 内存管理核心接口 ====== */ -void* smcc_malloc(usize size); -void* smcc_calloc(usize count, usize size); -void* smcc_realloc(void *ptr, usize new_size); +void *smcc_malloc(usize size); +void *smcc_calloc(usize count, usize size); +void *smcc_realloc(void *ptr, usize new_size); void smcc_free(void *ptr); /* ====== 文件系统核心接口 ====== */ /* 文件句柄 - 不透明指针 */ -typedef struct smcc_file* smcc_file_t; +typedef struct smcc_file *smcc_file_t; /* 文件打开模式 - 只保留编译器真正需要的 */ typedef enum { - SMCC_FILE_READ, /* 读取源文件、头文件 */ - SMCC_FILE_WRITE, /* 写入目标文件、汇编文件 */ - SMCC_FILE_APPEND /* 日志、调试输出 */ + SMCC_FILE_READ, /* 读取源文件、头文件 */ + SMCC_FILE_WRITE, /* 写入目标文件、汇编文件 */ + SMCC_FILE_APPEND /* 日志、调试输出 */ } smcc_file_mode_t; /* 核心文件操作 */ diff --git a/runtime/libcore/include/core_log.h b/runtime/libcore/include/core_log.h index 61e5233..d53938e 100644 --- a/runtime/libcore/include/core_log.h +++ b/runtime/libcore/include/core_log.h @@ -2,17 +2,16 @@ #define __SMCC_CORE_LOG_H__ #ifndef log_snprintf -#define log_snprintf smcc_snprintf +#define log_snprintf smcc_snprintf #endif #ifndef log_printf -#define log_printf smcc_printf +#define log_printf smcc_printf #endif #ifndef log_exit -#define log_exit smcc_exit +#define log_exit smcc_exit #endif #include - #endif /* __SMCC_CORE_LOG_H__ */ diff --git a/runtime/libcore/include/core_mem.h b/runtime/libcore/include/core_mem.h index bc02cfd..0316929 100644 --- a/runtime/libcore/include/core_mem.h +++ b/runtime/libcore/include/core_mem.h @@ -1,14 +1,14 @@ #ifndef __SMCC_CORE_MEM_H__ -#define __SMCC_CORE_MEM_H__ +#define __SMCC_CORE_MEM_H__ #include "core_type.h" -void* smcc_memcpy(void *dest, const void *src, usize n); -void* smcc_memmove(void *dest, const void *src, usize n); -void* smcc_memset(void *s, int c, usize n); +void *smcc_memcpy(void *dest, const void *src, usize n); +void *smcc_memmove(void *dest, const void *src, usize n); +void *smcc_memset(void *s, int c, usize n); int smcc_memcmp(const void *s1, const void *s2, usize n); -static inline u32 smcc_strhash32(const char* s) { +static inline u32 smcc_strhash32(const char *s) { u32 hash = 2166136261u; // FNV-1a偏移基础值 while (*s) { hash ^= *s++; @@ -17,7 +17,7 @@ static inline u32 smcc_strhash32(const char* s) { return hash; } -static inline int smcc_strcmp(const char* s1, const char* s2) { +static inline int smcc_strcmp(const char *s1, const char *s2) { while (*s1 && *s2 && *s1 == *s2) { s1++; s2++; diff --git a/runtime/libcore/include/core_str.h b/runtime/libcore/include/core_str.h index a5414e4..06764c7 100644 --- a/runtime/libcore/include/core_str.h +++ b/runtime/libcore/include/core_str.h @@ -1,63 +1,52 @@ #ifndef __CORE_STR_H__ -#define __CORE_STR_H__ +#define __CORE_STR_H__ -#include "core_type.h" #include "core_impl.h" #include "core_log.h" +#include "core_type.h" typedef struct cstring { - char* data; - usize len; + usize size; usize cap; + char *data; } cstring_t; /** * 创建一个新的空字符串 */ static inline cstring_t cstring_new(void) { - return (cstring_t) { .data = null, .len = 0, .cap = 0 }; -} - -/** - * 使用指定容量创建字符串 - */ -static inline cstring_t cstring_with_capacity(usize capacity) { - char* data = null; - if (capacity > 0) { - data = (char*)smcc_malloc(capacity); - Assert(data != null); - } - return (cstring_t) { .data = data, .len = 0, .cap = capacity }; + return (cstring_t){.data = null, .size = 0, .cap = 0}; } /** * 从 C 字符串创建 Rust 风格字符串 */ -static inline cstring_t cstring_from_cstr(const char* s) { +static inline cstring_t cstring_from_cstr(const char *s) { if (s == null) { return cstring_new(); } usize len = 0; - const char* p = s; - while (*p++) len++; + const char *p = s; + while (*p++) + len++; - char* data = (char*)smcc_malloc(len + 1); + char *data = (char *)smcc_malloc(len + 1); Assert(data != null); smcc_memcpy(data, s, len); data[len] = '\0'; - return (cstring_t) { .data = data, .len = len, .cap = len }; + return (cstring_t){.data = data, .size = len + 1, .cap = len + 1}; } /** * 释放字符串资源 */ -static inline void cstring_free(cstring_t* str) { +static inline void cstring_free(cstring_t *str) { if (str && str->data && str->cap != 0) { smcc_free(str->data); str->data = null; - str->len = 0; + str->size = 0; str->cap = 0; } } @@ -65,64 +54,67 @@ static inline void cstring_free(cstring_t* str) { /** * 向字符串追加内容 */ -static inline void cstring_push_cstr(cstring_t* str, const char* data, usize len) { +static inline void cstring_push_cstr(cstring_t *str, const char *data, + usize len) { if (str == null || data == null || len == 0) { return; } + if (str->cap == 0) { + str->size = 1; + } + // 如果需要扩容 - if (str->len + len + 1 > str->cap) { - // FIXME c string 兼容性问题 bad practice a lot of `+ 1` - usize new_cap = str->cap == 0 ? len + 1 : str->cap; - while (new_cap < str->len + len + 1) { + if (str->size + len > str->cap) { + usize new_cap = str->cap; + while (new_cap < str->size + len) { new_cap *= 2; - if (new_cap == 0) { // 处理溢出情况 - new_cap = str->len + len + 1; + // FIXME write by AI 处理溢出情况 + if (new_cap == 0) { + new_cap = str->size + len; break; } } - char* new_data = str->data ? - (char*)smcc_realloc(str->data, new_cap) : - (char*)smcc_malloc(new_cap); + char *new_data = (char *)smcc_realloc(str->data, new_cap); Assert(new_data != null); - + str->data = new_data; str->cap = new_cap; } - smcc_memcpy(str->data + str->len, data, len); - str->len += len; - str->data[str->len] = '\0'; // 保证 C 字符串兼容性 + smcc_memcpy(str->data + str->size - 1, data, len); + str->size += len; + str->data[str->size - 1] = '\0'; // 保证 C 字符串兼容性 } /** * 向字符串追加单个字符 */ -static inline void cstring_push(cstring_t* str, char ch) { +static inline void cstring_push(cstring_t *str, char ch) { cstring_push_cstr(str, &ch, 1); } /** * 获取字符串长度 */ -static inline usize cstring_len(const cstring_t* str) { - return str ? str->len : 0; +static inline usize cstring_len(const cstring_t *str) { + return str ? str->size - 1 : 0; } /** * 检查字符串是否为空 */ -static inline cbool cstring_is_empty(const cstring_t* str) { - return str == null || str->len == 0; +static inline cbool cstring_is_empty(const cstring_t *str) { + return str == null || str->size == 0; } /** * 清空字符串内容但保留分配的内存 */ -static inline void cstring_clear(cstring_t* str) { +static inline void cstring_clear(cstring_t *str) { if (str) { - str->len = 0; + str->size = 1; if (str->data) { str->data[0] = '\0'; } @@ -132,7 +124,7 @@ static inline void cstring_clear(cstring_t* str) { /** * 获取 C 风格字符串 */ -static inline const char* cstring_as_cstr(const cstring_t* str) { +static inline char *cstring_as_cstr(const cstring_t *str) { if (str == null || str->data == null) { return ""; } diff --git a/runtime/libcore/include/core_stream.h b/runtime/libcore/include/core_stream.h index 4b39363..edeaa0a 100644 --- a/runtime/libcore/include/core_stream.h +++ b/runtime/libcore/include/core_stream.h @@ -2,9 +2,9 @@ #define __SMCC_CORE_STREAM_H__ #include "core_impl.h" +#include "core_macro.h" #include "core_mem.h" #include "core_str.h" -#include "core_macro.h" typedef struct core_stream core_stream_t; @@ -14,52 +14,53 @@ struct core_stream { cstring_t name; /// @brief 读取指定数量的字符到缓冲区 - usize (*read_buf)(core_stream_t* stream, char* buffer, usize count); + usize (*read_buf)(core_stream_t *stream, char *buffer, usize count); /// @brief 获取下一个字符 - int (*peek_char)(core_stream_t* stream); + int (*peek_char)(core_stream_t *stream); /// @brief 重置字符流位置 - void (*reset_char) (core_stream_t* stream); + void (*reset_char)(core_stream_t *stream); /// @brief 读取并消费下一个字符(移动流位置) - int (*next_char)(core_stream_t* stream); + int (*next_char)(core_stream_t *stream); /// @brief 释放资源 - void (*free_stream) (core_stream_t* steam); + void (*free_stream)(core_stream_t *steam); }; -static inline usize core_stream_read_buf(core_stream_t* self, char* buffer, usize count) { +static inline usize core_stream_read_buf(core_stream_t *self, char *buffer, + usize count) { return self->read_buf(self, buffer, count); } -static inline int core_stream_peek_char(core_stream_t* self) { +static inline int core_stream_peek_char(core_stream_t *self) { return self->peek_char(self); } -static inline void core_stream_reset_char(core_stream_t* self) { +static inline void core_stream_reset_char(core_stream_t *self) { self->reset_char(self); } -static inline int core_stream_next_char(core_stream_t* self) { +static inline int core_stream_next_char(core_stream_t *self) { return self->next_char(self); } -static inline void core_stream_free_stream(core_stream_t* self) { +static inline void core_stream_free_stream(core_stream_t *self) { self->free_stream(self); } #ifndef __SMCC_CORE_NO_MEM_STREAM__ typedef struct core_mem_stream { core_stream_t stream; - const char* data; + const char *data; usize data_length; usize curr_pos; usize peek_pos; cbool owned; } core_mem_stream_t; -core_stream_t* core_mem_stream_init(core_mem_stream_t* stream, const char* data, usize length, cbool need_copy); +core_stream_t *core_mem_stream_init(core_mem_stream_t *stream, const char *data, + usize length, cbool need_copy); #endif - #endif /* __SMCC_CORE_STREAM_H__ */ diff --git a/runtime/libcore/include/core_type.h b/runtime/libcore/include/core_type.h index d73d4bd..a0624c2 100644 --- a/runtime/libcore/include/core_type.h +++ b/runtime/libcore/include/core_type.h @@ -1,12 +1,13 @@ #ifndef __SMCC_CORE_TYPE_H__ -#define __SMCC_CORE_TYPE_H__ +#define __SMCC_CORE_TYPE_H__ #ifndef __SMCC_BUILTIN_TYPE__ -#include -#include -#include #include +#include +#include +#include +/* clang-format off */ typedef int8_t i8; typedef int16_t i16; typedef int32_t i32; @@ -27,6 +28,7 @@ typedef bool cbool; /// void / null #define null NULL +/* clang-format on */ static_assert(sizeof(cbool) == 1, "cbool size must 1"); #else @@ -60,7 +62,7 @@ typedef union core_cvalue { /* string value */ struct { - char* data; + char *data; uintptr_t len; } cstr; diff --git a/runtime/libcore/include/core_vec.h b/runtime/libcore/include/core_vec.h new file mode 100644 index 0000000..ca49e3c --- /dev/null +++ b/runtime/libcore/include/core_vec.h @@ -0,0 +1,115 @@ +/** + * @file vec.h + * @brief 动态数组(Dynamic Array)实现 + * + * 提供类型安全的动态数组容器实现,支持自动扩容和基本操作 + */ + +#ifndef __SMCC_CORE_DARRAY_H__ +#define __SMCC_CORE_DARRAY_H__ + +#include "core_impl.h" +#include "core_type.h" + +#define __vec_realloc smcc_realloc +#define __vec_free smcc_free + +/** @defgroup vec_struct 数据结构定义 */ + +/** + * @def VEC(name, type) + * @brief 声明向量结构体 + * @param name 结构体变量名 + * @param type 存储的数据类型 + * + * 生成包含size/cap/data三个字段的结构体定义: + * - size: 当前元素数量 + * - cap: 数组容量 + * - data: 存储数组指针 + */ +#define VEC(name, type) \ + struct { \ + usize size; \ + usize cap; \ + type *data; \ + } name + +/** @defgroup vec_operations 动态数组操作宏 */ + +/** + * @def vec_init(vec) + * @brief 初始化向量结构体 + * @param vec 要初始化的向量结构体变量 + * + * @note 此宏不会分配内存,仅做零初始化 + */ +#define vec_init(vec) \ + do { \ + (vec).size = 0, (vec).cap = 0, (vec).data = 0; \ + } while (0) + +/** + * @def vec_push(vec, value) + * @brief 添加元素到向量末尾 + * @param vec 目标向量结构体 + * @param value 要添加的值(需匹配存储类型) + * + * @note 当容量不足时自动扩容为2倍(初始容量为4) + * @warning 内存分配失败时会触发LOG_FATAL + */ +#define vec_push(vec, value) \ + do { \ + if (vec.size >= vec.cap) { \ + int cap = vec.cap ? vec.cap * 2 : 4; \ + void *data = __vec_realloc(vec.data, cap * sizeof(*vec.data)); \ + if (!data) { \ + LOG_FATAL("vector_push: realloc failed\n"); \ + } \ + (vec).cap = cap; \ + (vec).data = data; \ + } \ + (vec).data[(vec).size++] = value; \ + } while (0) + +/** + * @def vec_pop(vec) + * @brief 弹出最后一个元素 + * @param vec 目标向量结构体 + * @return 最后元素的引用 + * @warning 需确保size > 0时使用 + */ +#define vec_pop(vec) ((vec).data[--(vec).size]) + +/** + * @def vec_at(vec, idx) + * @brief 获取指定索引元素 + * @param vec 目标向量结构体 + * @param idx 元素索引(0 <= idx < size) + * @return 对应元素的引用 + */ +#define vec_at(vec, idx) (((vec).data)[idx]) + +/** + * @def vec_idx(vec, ptr) + * @brief 获取元素指针对应的索引 + * @param vec 目标向量结构体 + * @param ptr 元素指针(需在data数组范围内) + * @return 元素索引值 + */ +#define vec_idx(vec, ptr) ((ptr) - (vec).data) + +/** + * @def vec_free(vec) + * @brief 释放向量内存 + * @param vec 目标向量结构体 + * + * @note 释放后需重新初始化才能再次使用 + */ +#define vec_free(vec) \ + do { \ + __vec_free((vec).data); \ + (vec).data = NULL; \ + (vec).size = (vec).cap = 0; \ + } while (0) + +#endif // __SMCC_CORE_DARRAY_H__ diff --git a/runtime/libcore/include/libcore.h b/runtime/libcore/include/libcore.h index 3cd084d..1eebeb3 100644 --- a/runtime/libcore/include/libcore.h +++ b/runtime/libcore/include/libcore.h @@ -1,14 +1,14 @@ #ifndef __SMCC_CORE_H__ #define __SMCC_CORE_H__ -#include #include #include +#include #define __SMCC_LOG_NO_STD_IMPL__ -#define log_snprintf smcc_snprintf -#define log_printf smcc_eprintf -#define log_exit smcc_exit +#define log_snprintf smcc_snprintf +#define log_printf smcc_eprintf +#define log_exit smcc_exit #include #define _SMCC_STR(str) #str @@ -17,5 +17,6 @@ #define SMCC_ARRLEN(arr) (sizeof(arr) / sizeof(arr[0])) #include #include +#include #endif // __SMCC_CORE_H__ diff --git a/runtime/libcore/src/cfg.std_impl.c b/runtime/libcore/src/cfg.std_impl.c index 6546265..0cafb5c 100644 --- a/runtime/libcore/src/cfg.std_impl.c +++ b/runtime/libcore/src/cfg.std_impl.c @@ -4,69 +4,68 @@ #include #define __SMCC_LOG_IMPORT_SRC__ -#define log_snprintf smcc_snprintf -#define log_printf smcc_printf -#define log_exit smcc_exit +#define log_snprintf smcc_snprintf +#define log_printf smcc_printf +#define log_exit smcc_exit #include +#include #include #include -#include #include /* ====== 内存管理核心接口实现 ====== */ -void* smcc_malloc(usize size) { - return malloc(size); -} +void *smcc_malloc(usize size) { return malloc(size); } -void* smcc_calloc(usize count, usize size) { - return calloc(count, size); -} +void *smcc_calloc(usize count, usize size) { return calloc(count, size); } -void* smcc_realloc(void *ptr, usize new_size) { - return realloc(ptr, new_size); -} +void *smcc_realloc(void *ptr, usize new_size) { return realloc(ptr, new_size); } -void smcc_free(void *ptr) { - free(ptr); -} +void smcc_free(void *ptr) { free(ptr); } /* ====== 文件系统核心接口实现 ====== */ -static const char* get_file_mode_string(smcc_file_mode_t mode) { +static const char *get_file_mode_string(smcc_file_mode_t mode) { switch (mode) { - case SMCC_FILE_READ: return "rb"; - case SMCC_FILE_WRITE: return "wb"; - case SMCC_FILE_APPEND: return "ab"; - default: return "rb"; + case SMCC_FILE_READ: + return "rb"; + case SMCC_FILE_WRITE: + return "wb"; + case SMCC_FILE_APPEND: + return "ab"; + default: + return "rb"; } } smcc_file_t smcc_fopen(const char *path, smcc_file_mode_t mode) { - const char* mode_str = get_file_mode_string(mode); + const char *mode_str = get_file_mode_string(mode); return (smcc_file_t)fopen(path, mode_str); } void smcc_fclose(smcc_file_t file) { if (file) { - fclose((FILE*)file); + fclose((FILE *)file); } } usize smcc_fread(smcc_file_t file, void *buffer, usize size) { - if (!file || !buffer) return 0; - return fread(buffer, 1, size, (FILE*)file); + if (!file || !buffer) + return 0; + return fread(buffer, 1, size, (FILE *)file); } usize smcc_fwrite(smcc_file_t file, const void *buffer, usize size) { - if (!file || !buffer) return 0; - return fwrite(buffer, 1, size, (FILE*)file); + if (!file || !buffer) + return 0; + return fwrite(buffer, 1, size, (FILE *)file); } cbool smcc_fexists(const char *path) { smcc_file_t fp = smcc_fopen(path, SMCC_FILE_READ); - if (!fp) return false; + if (!fp) + return false; smcc_fclose(fp); return true; } @@ -96,6 +95,4 @@ void smcc_eprintf(const char *format, ...) { /* ====== 系统核心接口实现 ====== */ -void smcc_exit(int code) { - exit(code); -} \ No newline at end of file +void smcc_exit(int code) { exit(code); } \ No newline at end of file diff --git a/runtime/libcore/src/memory.c b/runtime/libcore/src/memory.c index 2d3fc66..ccc0e67 100644 --- a/runtime/libcore/src/memory.c +++ b/runtime/libcore/src/memory.c @@ -2,50 +2,68 @@ #include // 判断是否支持非对齐访问(x86/x64 支持) -#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64) +#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || \ + defined(_M_X64) #define UNALIGNED_ACCESS_ALLOWED 1 #else #define UNALIGNED_ACCESS_ALLOWED 0 #endif -void* smcc_memcpy(void * dest, const void * restrict src, usize n) { - char* d = (char*)dest; - const char* s = (const char*)src; +void *smcc_memcpy(void *dest, const void *restrict src, usize n) { + char *d = (char *)dest; + const char *s = (const char *)src; // 快速路径:小内存拷贝 if (n <= 16) { - switch(n) { - case 16: d[15] = s[15]; /* fall through */ - case 15: d[14] = s[14]; /* fall through */ - case 14: d[13] = s[13]; /* fall through */ - case 13: d[12] = s[12]; /* fall through */ - case 12: d[11] = s[11]; /* fall through */ - case 11: d[10] = s[10]; /* fall through */ - case 10: d[9] = s[9]; /* fall through */ - case 9: d[8] = s[8]; /* fall through */ - case 8: d[7] = s[7]; /* fall through */ - case 7: d[6] = s[6]; /* fall through */ - case 6: d[5] = s[5]; /* fall through */ - case 5: d[4] = s[4]; /* fall through */ - case 4: d[3] = s[3]; /* fall through */ - case 3: d[2] = s[2]; /* fall through */ - case 2: d[1] = s[1]; /* fall through */ - case 1: d[0] = s[0]; /* fall through */ - default: break; + switch (n) { + case 16: + d[15] = s[15]; /* fall through */ + case 15: + d[14] = s[14]; /* fall through */ + case 14: + d[13] = s[13]; /* fall through */ + case 13: + d[12] = s[12]; /* fall through */ + case 12: + d[11] = s[11]; /* fall through */ + case 11: + d[10] = s[10]; /* fall through */ + case 10: + d[9] = s[9]; /* fall through */ + case 9: + d[8] = s[8]; /* fall through */ + case 8: + d[7] = s[7]; /* fall through */ + case 7: + d[6] = s[6]; /* fall through */ + case 6: + d[5] = s[5]; /* fall through */ + case 5: + d[4] = s[4]; /* fall through */ + case 4: + d[3] = s[3]; /* fall through */ + case 3: + d[2] = s[2]; /* fall through */ + case 2: + d[1] = s[1]; /* fall through */ + case 1: + d[0] = s[0]; /* fall through */ + default: + break; } return dest; } #if UNALIGNED_ACCESS_ALLOWED // 按8字节批量复制(适用于支持非对齐访问的平台) - uint64_t* d64 = (uint64_t*)d; - const uint64_t* s64 = (const uint64_t*)s; + uint64_t *d64 = (uint64_t *)d; + const uint64_t *s64 = (const uint64_t *)s; while (n >= 8) { *d64++ = *s64++; n -= 8; } - d = (char*)d64; - s = (const char*)s64; + d = (char *)d64; + s = (const char *)s64; #endif // 处理剩余字节 @@ -56,10 +74,9 @@ void* smcc_memcpy(void * dest, const void * restrict src, usize n) { return dest; } -void *smcc_memmove(void *dest, const void *src, usize n) -{ - char* d = (char*)dest; - const char* s = (const char*)src; +void *smcc_memmove(void *dest, const void *src, usize n) { + char *d = (char *)dest; + const char *s = (const char *)src; // 地址相同直接返回 if (d == s) { @@ -81,51 +98,65 @@ void *smcc_memmove(void *dest, const void *src, usize n) return dest; } -void* smcc_memset(void *s, int c, usize n) { - unsigned char* p = (unsigned char*)s; +void *smcc_memset(void *s, int c, usize n) { + unsigned char *p = (unsigned char *)s; unsigned char byte_val = (unsigned char)c; // 快速设置小块内存 if (n <= 16) { - switch(n) { - case 16: p[15] = byte_val; /* fall through */ - case 15: p[14] = byte_val; /* fall through */ - case 14: p[13] = byte_val; /* fall through */ - case 13: p[12] = byte_val; /* fall through */ - case 12: p[11] = byte_val; /* fall through */ - case 11: p[10] = byte_val; /* fall through */ - case 10: p[9] = byte_val; /* fall through */ - case 9: p[8] = byte_val; /* fall through */ - case 8: p[7] = byte_val; /* fall through */ - case 7: p[6] = byte_val; /* fall through */ - case 6: p[5] = byte_val; /* fall through */ - case 5: p[4] = byte_val; /* fall through */ - case 4: p[3] = byte_val; /* fall through */ - case 3: p[2] = byte_val; /* fall through */ - case 2: p[1] = byte_val; /* fall through */ - case 1: p[0] = byte_val; /* fall through */ - default: break; + switch (n) { + case 16: + p[15] = byte_val; /* fall through */ + case 15: + p[14] = byte_val; /* fall through */ + case 14: + p[13] = byte_val; /* fall through */ + case 13: + p[12] = byte_val; /* fall through */ + case 12: + p[11] = byte_val; /* fall through */ + case 11: + p[10] = byte_val; /* fall through */ + case 10: + p[9] = byte_val; /* fall through */ + case 9: + p[8] = byte_val; /* fall through */ + case 8: + p[7] = byte_val; /* fall through */ + case 7: + p[6] = byte_val; /* fall through */ + case 6: + p[5] = byte_val; /* fall through */ + case 5: + p[4] = byte_val; /* fall through */ + case 4: + p[3] = byte_val; /* fall through */ + case 3: + p[2] = byte_val; /* fall through */ + case 2: + p[1] = byte_val; /* fall through */ + case 1: + p[0] = byte_val; /* fall through */ + default: + break; } return s; } #if UNALIGNED_ACCESS_ALLOWED // 构造一个8字节值用于批量填充 - uint64_t fill_val = ((uint64_t)byte_val << 56) | - ((uint64_t)byte_val << 48) | - ((uint64_t)byte_val << 40) | - ((uint64_t)byte_val << 32) | - ((uint64_t)byte_val << 24) | - ((uint64_t)byte_val << 16) | - ((uint64_t)byte_val << 8) | - (uint64_t)byte_val; + uint64_t fill_val = + ((uint64_t)byte_val << 56) | ((uint64_t)byte_val << 48) | + ((uint64_t)byte_val << 40) | ((uint64_t)byte_val << 32) | + ((uint64_t)byte_val << 24) | ((uint64_t)byte_val << 16) | + ((uint64_t)byte_val << 8) | (uint64_t)byte_val; - uint64_t* p64 = (uint64_t*)p; + uint64_t *p64 = (uint64_t *)p; while (n >= 8) { *p64++ = fill_val; n -= 8; } - p = (unsigned char*)p64; + p = (unsigned char *)p64; #endif // 设置剩余字节 @@ -137,67 +168,150 @@ void* smcc_memset(void *s, int c, usize n) { } int smcc_memcmp(const void *s1, const void *s2, usize n) { - const unsigned char* p1 = (const unsigned char*)s1; - const unsigned char* p2 = (const unsigned char*)s2; + const unsigned char *p1 = (const unsigned char *)s1; + const unsigned char *p2 = (const unsigned char *)s2; // 快速比较小块内存 if (n <= 16) { unsigned char diff = 0; - switch(n) { - case 16: diff |= (p1[15] ^ p2[15]); /* fall through */ - case 15: diff |= (p1[14] ^ p2[14]); /* fall through */ - case 14: diff |= (p1[13] ^ p2[13]); /* fall through */ - case 13: diff |= (p1[12] ^ p2[12]); /* fall through */ - case 12: diff |= (p1[11] ^ p2[11]); /* fall through */ - case 11: diff |= (p1[10] ^ p2[10]); /* fall through */ - case 10: diff |= (p1[9] ^ p2[9]); /* fall through */ - case 9: diff |= (p1[8] ^ p2[8]); /* fall through */ - case 8: diff |= (p1[7] ^ p2[7]); /* fall through */ - case 7: diff |= (p1[6] ^ p2[6]); /* fall through */ - case 6: diff |= (p1[5] ^ p2[5]); /* fall through */ - case 5: diff |= (p1[4] ^ p2[4]); /* fall through */ - case 4: diff |= (p1[3] ^ p2[3]); /* fall through */ - case 3: diff |= (p1[2] ^ p2[2]); /* fall through */ - case 2: diff |= (p1[1] ^ p2[1]); /* fall through */ - case 1: diff |= (p1[0] ^ p2[0]); /* fall through */ - default: break; + switch (n) { + case 16: + diff |= (p1[15] ^ p2[15]); /* fall through */ + case 15: + diff |= (p1[14] ^ p2[14]); /* fall through */ + case 14: + diff |= (p1[13] ^ p2[13]); /* fall through */ + case 13: + diff |= (p1[12] ^ p2[12]); /* fall through */ + case 12: + diff |= (p1[11] ^ p2[11]); /* fall through */ + case 11: + diff |= (p1[10] ^ p2[10]); /* fall through */ + case 10: + diff |= (p1[9] ^ p2[9]); /* fall through */ + case 9: + diff |= (p1[8] ^ p2[8]); /* fall through */ + case 8: + diff |= (p1[7] ^ p2[7]); /* fall through */ + case 7: + diff |= (p1[6] ^ p2[6]); /* fall through */ + case 6: + diff |= (p1[5] ^ p2[5]); /* fall through */ + case 5: + diff |= (p1[4] ^ p2[4]); /* fall through */ + case 4: + diff |= (p1[3] ^ p2[3]); /* fall through */ + case 3: + diff |= (p1[2] ^ p2[2]); /* fall through */ + case 2: + diff |= (p1[1] ^ p2[1]); /* fall through */ + case 1: + diff |= (p1[0] ^ p2[0]); /* fall through */ + default: + break; } // 只有当所有字节都相等时diff才为0 - if (!diff) return 0; - + if (!diff) + return 0; + // 找到第一个不同的字节并返回差值 size_t i = 0; - switch(n) { - case 16: if(p1[15] != p2[15]) {i=15;break;} - case 15: if(p1[14] != p2[14]) {i=14;break;} - case 14: if(p1[13] != p2[13]) {i=13;break;} - case 13: if(p1[12] != p2[12]) {i=12;break;} - case 12: if(p1[11] != p2[11]) {i=11;break;} - case 11: if(p1[10] != p2[10]) {i=10;break;} - case 10: if(p1[9] != p2[9]) {i=9;break;} - case 9: if(p1[8] != p2[8]) {i=8;break;} - case 8: if(p1[7] != p2[7]) {i=7;break;} - case 7: if(p1[6] != p2[6]) {i=6;break;} - case 6: if(p1[5] != p2[5]) {i=5;break;} - case 5: if(p1[4] != p2[4]) {i=4;break;} - case 4: if(p1[3] != p2[3]) {i=3;break;} - case 3: if(p1[2] != p2[2]) {i=2;break;} - case 2: if(p1[1] != p2[1]) {i=1;break;} - case 1: if(p1[0] != p2[0]) {i=0;break;} - default: break; + switch (n) { + case 16: + if (p1[15] != p2[15]) { + i = 15; + break; + } + case 15: + if (p1[14] != p2[14]) { + i = 14; + break; + } + case 14: + if (p1[13] != p2[13]) { + i = 13; + break; + } + case 13: + if (p1[12] != p2[12]) { + i = 12; + break; + } + case 12: + if (p1[11] != p2[11]) { + i = 11; + break; + } + case 11: + if (p1[10] != p2[10]) { + i = 10; + break; + } + case 10: + if (p1[9] != p2[9]) { + i = 9; + break; + } + case 9: + if (p1[8] != p2[8]) { + i = 8; + break; + } + case 8: + if (p1[7] != p2[7]) { + i = 7; + break; + } + case 7: + if (p1[6] != p2[6]) { + i = 6; + break; + } + case 6: + if (p1[5] != p2[5]) { + i = 5; + break; + } + case 5: + if (p1[4] != p2[4]) { + i = 4; + break; + } + case 4: + if (p1[3] != p2[3]) { + i = 3; + break; + } + case 3: + if (p1[2] != p2[2]) { + i = 2; + break; + } + case 2: + if (p1[1] != p2[1]) { + i = 1; + break; + } + case 1: + if (p1[0] != p2[0]) { + i = 0; + break; + } + default: + break; } return p1[i] - p2[i]; } #if UNALIGNED_ACCESS_ALLOWED // 按8字节批量比较 - const uint64_t* p1_64 = (const uint64_t*)p1; - const uint64_t* p2_64 = (const uint64_t*)p2; + const uint64_t *p1_64 = (const uint64_t *)p1; + const uint64_t *p2_64 = (const uint64_t *)p2; while (n >= 8) { if (*p1_64 != *p2_64) { // 发现不同,在8字节内定位具体位置 - const unsigned char* b1 = (const unsigned char*)p1_64; - const unsigned char* b2 = (const unsigned char*)p2_64; + const unsigned char *b1 = (const unsigned char *)p1_64; + const unsigned char *b2 = (const unsigned char *)p2_64; for (int j = 0; j < 8; j++) { if (b1[j] != b2[j]) return b1[j] - b2[j]; @@ -207,8 +321,8 @@ int smcc_memcmp(const void *s1, const void *s2, usize n) { p2_64++; n -= 8; } - p1 = (const unsigned char*)p1_64; - p2 = (const unsigned char*)p2_64; + p1 = (const unsigned char *)p1_64; + p2 = (const unsigned char *)p2_64; #endif // 比较剩余字节 diff --git a/runtime/libcore/src/stream.c b/runtime/libcore/src/stream.c index c613f29..2e391f8 100644 --- a/runtime/libcore/src/stream.c +++ b/runtime/libcore/src/stream.c @@ -2,9 +2,9 @@ #include // 内存流的具体实现结构 -static usize read_buf(core_stream_t* _stream, char* buffer, usize count) { +static usize read_buf(core_stream_t *_stream, char *buffer, usize count) { Assert(buffer != null && buffer != null); - core_mem_stream_t* stream = (core_mem_stream_t*)_stream; + core_mem_stream_t *stream = (core_mem_stream_t *)_stream; usize remaining = stream->data_length - stream->curr_pos; usize to_read = (remaining < count) ? remaining : count; @@ -13,15 +13,16 @@ static usize read_buf(core_stream_t* _stream, char* buffer, usize count) { smcc_memcpy(buffer, stream->data + stream->curr_pos, to_read); stream->curr_pos += to_read; } else { - LOG_WARN("Reading past end of stream [maybe count is too large or negative?]"); + LOG_WARN("Reading past end of stream " + "[maybe count is too large or negative?]"); } return to_read; } -static int peek_char(core_stream_t* _stream) { +static int peek_char(core_stream_t *_stream) { Assert(_stream != null); - core_mem_stream_t* stream = (core_mem_stream_t*)_stream; + core_mem_stream_t *stream = (core_mem_stream_t *)_stream; // 如果已经到达末尾,返回EOF if (stream->peek_pos >= stream->data_length) { @@ -31,15 +32,15 @@ static int peek_char(core_stream_t* _stream) { return (int)(unsigned char)stream->data[stream->peek_pos++]; } -static int next_char(core_stream_t* _stream) { +static int next_char(core_stream_t *_stream) { Assert(_stream != NULL); - core_mem_stream_t* stream = (core_mem_stream_t*)_stream; + core_mem_stream_t *stream = (core_mem_stream_t *)_stream; // 如果已经到达末尾,返回EOF if (stream->curr_pos >= stream->data_length) { return core_stream_eof; // EOF } - + unsigned char ch = stream->data[stream->curr_pos++]; if (stream->peek_pos < stream->curr_pos) { stream->peek_pos = stream->curr_pos; @@ -47,26 +48,27 @@ static int next_char(core_stream_t* _stream) { return (int)ch; } -static void reset_char(core_stream_t* _stream) { +static void reset_char(core_stream_t *_stream) { Assert(_stream != NULL); - core_mem_stream_t* stream = (core_mem_stream_t*)_stream; + core_mem_stream_t *stream = (core_mem_stream_t *)_stream; stream->peek_pos = stream->curr_pos; } -static void free_stream(core_stream_t* _stream) { +static void free_stream(core_stream_t *_stream) { Assert(_stream != null); - core_mem_stream_t* stream = (core_mem_stream_t*)_stream; + core_mem_stream_t *stream = (core_mem_stream_t *)_stream; // FIXME maybe double free? cstring_free(&stream->stream.name); if (stream->owned) { - smcc_free((void*)stream->data); + smcc_free((void *)stream->data); } } -core_stream_t* core_mem_stream_init(core_mem_stream_t* stream, const char* data, usize length, cbool need_copy) { +core_stream_t *core_mem_stream_init(core_mem_stream_t *stream, const char *data, + usize length, cbool need_copy) { if (stream == null || data == NULL || length == 0) { LOG_ERROR("param error"); return null; @@ -74,7 +76,7 @@ core_stream_t* core_mem_stream_init(core_mem_stream_t* stream, const char* data, stream->owned = need_copy; if (need_copy) { - char* buf = (char*)smcc_malloc(length); + char *buf = (char *)smcc_malloc(length); if (buf == null) { LOG_ERROR("malloc error"); return null; @@ -90,12 +92,12 @@ core_stream_t* core_mem_stream_init(core_mem_stream_t* stream, const char* data, stream->peek_pos = 0; stream->stream.name = cstring_from_cstr("mem_stream"); - + stream->stream.read_buf = read_buf; stream->stream.peek_char = peek_char; stream->stream.next_char = next_char; stream->stream.reset_char = reset_char; stream->stream.free_stream = free_stream; - return (void*)stream; + return (void *)stream; } diff --git a/runtime/libutils/include/hashtable.h b/runtime/libutils/include/hashtable.h index 86b0dcd..02f5521 100644 --- a/runtime/libutils/include/hashtable.h +++ b/runtime/libutils/include/hashtable.h @@ -1,7 +1,7 @@ /** * @file hashtable.h * @brief 开放寻址法哈希表实现 - * + * * 提供基于向量容器的哈希表实现,支持动态扩容和墓碑机制 */ @@ -9,7 +9,6 @@ #define __SMCC_HASHTABLE_H__ #include -#include "vector.h" /** * @enum ht_entry_state_t @@ -24,48 +23,48 @@ typedef enum hash_table_entry_state { /** * @struct hash_entry_t * @brief 哈希表条目结构 - * + * * @note key/value内存由调用者管理,哈希表不负责其生命周期 */ typedef struct hash_entry { - const void* key; /**< 键指针(不可变) */ - void* value; /**< 值指针 */ - u32 hash; /**< 预计算的哈希值(避免重复计算) */ + const void *key; /**< 键指针(不可变) */ + void *value; /**< 值指针 */ + u32 hash; /**< 预计算的哈希值(避免重复计算) */ ht_entry_state_t state; /**< 当前条目状态 */ } hash_entry_t; /** * @struct hash_table_t * @brief 哈希表主体结构 - * + * * 使用开放寻址法实现,采用墓碑标记处理删除操作 */ typedef struct hash_table { - VECTOR_HEADER(entries, hash_entry_t); /**< 条目存储容器 */ - u32 count; /**< 有效条目数量(不含墓碑) */ - u32 tombstone_count; /**< 墓碑条目数量 */ + VECTOR_HEADER(entries, hash_entry_t); /**< 条目存储容器 */ + u32 count; /**< 有效条目数量(不含墓碑) */ + u32 tombstone_count; /**< 墓碑条目数量 */ /** * @brief 哈希函数指针 * @param key 键指针 * @return 32位无符号哈希值 */ - u32 (*hash_func)(const void* key); + u32 (*hash_func)(const void *key); /** * @brief 键比较函数指针 * @param key1 第一个键指针 * @param key2 第二个键指针 * @return 相同返回0,不同返回非0 */ - int(*key_cmp)(const void* key1, const void* key2); + int (*key_cmp)(const void *key1, const void *key2); } hash_table_t; /** * @brief 初始化哈希表结构 * @param ht 哈希表实例指针 - * + * * @warning 必须设置hash_func和key_cmp后才能使用 */ -void init_hashtable(hash_table_t* ht); +void init_hashtable(hash_table_t *ht); /** * @brief 插入/更新键值对 @@ -74,7 +73,7 @@ void init_hashtable(hash_table_t* ht); * @param value 值指针 * @return 被替换的旧值指针(无替换返回NULL) */ -void* hashtable_set(hash_table_t* ht, const void* key, void* value); +void *hashtable_set(hash_table_t *ht, const void *key, void *value); /** * @brief 查找键对应值 @@ -82,25 +81,25 @@ void* hashtable_set(hash_table_t* ht, const void* key, void* value); * @param key 查找键指针 * @return 找到返回值指针,未找到返回NULL */ -void* hashtable_get(hash_table_t* ht, const void* key); +void *hashtable_get(hash_table_t *ht, const void *key); /** * @brief 删除键值对 * @param ht 哈希表实例指针 * @param key 要删除的键指针 * @return 被删除的值指针(不存在返回NULL) - * + * * @note 实际采用墓碑标记方式删除 */ -void* hashtable_del(hash_table_t* ht, const void* key); +void *hashtable_del(hash_table_t *ht, const void *key); /** * @brief 销毁哈希表 * @param ht 哈希表实例指针 - * + * * @note 仅释放哈希表内部内存,不会释放key/value内存 */ -void hashtable_destory(hash_table_t* ht); +void hashtable_destory(hash_table_t *ht); /** * @typedef hash_table_iter_func @@ -110,7 +109,8 @@ void hashtable_destory(hash_table_t* ht); * @param context 用户上下文指针 * @return 返回非0停止迭代 */ -typedef int (*hash_table_iter_func)(const void* key, void* value, void* context); +typedef int (*hash_table_iter_func)(const void *key, void *value, + void *context); /** * @brief 遍历哈希表所有有效条目 @@ -118,6 +118,7 @@ typedef int (*hash_table_iter_func)(const void* key, void* value, void* context) * @param iter_func 迭代回调函数 * @param context 用户上下文指针 */ -void hashtable_foreach(hash_table_t* ht, hash_table_iter_func iter_func, void* context); +void hashtable_foreach(hash_table_t *ht, hash_table_iter_func iter_func, + void *context); #endif // __SMCC_HASHTABLE_H__ diff --git a/runtime/libutils/include/kllist.h b/runtime/libutils/include/kllist.h index d6c9d59..8b41850 100644 --- a/runtime/libutils/include/kllist.h +++ b/runtime/libutils/include/kllist.h @@ -3,7 +3,8 @@ * @link https://njusecourse.feishu.cn/wiki/I8vkw2zkwiEInUkujTJc7zzOnwf * @link https://kernelnewlbies.org/FAQ/LinkedLists * @link https://lwn.net/Articles/887097/ - * @link https://liuluheng.github.io/wiki/public_html/Embedded-System/kernel/list-and-hlist.html + * @link + * https://liuluheng.github.io/wiki/public_html/Embedded-System/kernel/list-and-hlist.html */ #ifndef __KLLIST_H__ @@ -18,13 +19,17 @@ // Magic: https://radek.io/posts/magical-container_of-macro/ // StackOverflow: https://stackoverflow.com/q/15832301/1833118 #ifdef __GNUC__ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) +#define container_of(ptr, type, member) \ + ({ \ + const typeof(((type *)0)->member) *__mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); \ + }) #else -#define container_of(ptr, type, member) ({ \ - const void *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) +#define container_of(ptr, type, member) \ + ({ \ + const void *__mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); \ + }) #endif #endif @@ -37,26 +42,25 @@ struct list_head { /** * list init - * @example + * @example * 1. struct list_head your_list = LIST_HEAD_INIT(your_list); * 2. struct list_head your_list; INIT_LIST_HEAD(&your_list); - * 3. LIST_HEAD(your_list); => struct your_list = { &(your_list), &(your_list) }; + * 3. LIST_HEAD(your_list); => struct your_list = { &(your_list), &(your_list) + * }; */ -#define LIST_HEAD_INIT(name) { &(name), &(name) } +#define LIST_HEAD_INIT(name) {&(name), &(name)} static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list; list->prev = list; } -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) +#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name) /** * list add */ -static inline void __list_add(struct list_head *newl, - struct list_head *prev, +static inline void __list_add(struct list_head *newl, struct list_head *prev, struct list_head *next) { next->prev = newl; newl->next = next; @@ -68,7 +72,8 @@ static inline void list_add(struct list_head *newl, struct list_head *head) { __list_add(newl, head, head->next); } -static inline void list_add_tail(struct list_head *newl, struct list_head *head) { +static inline void list_add_tail(struct list_head *newl, + struct list_head *head) { __list_add(newl, head->prev, head); } @@ -76,7 +81,7 @@ static inline void list_add_tail(struct list_head *newl, struct list_head *head) * list delete */ -static inline void __list_del(struct list_head * prev, struct list_head * next) { +static inline void __list_del(struct list_head *prev, struct list_head *next) { next->prev = prev; prev->next = next; } @@ -84,7 +89,7 @@ static inline void __list_del(struct list_head * prev, struct list_head * next) static inline void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); entry->next = NULL; - entry->prev = NULL; + entry->prev = NULL; } /** @@ -92,8 +97,9 @@ static inline void list_del(struct list_head *entry) { * @list: the entry to test * @head: the head of the list */ -static inline int list_is_first(const struct list_head *list, const struct list_head *head) { - return list->prev == head; +static inline int list_is_first(const struct list_head *list, + const struct list_head *head) { + return list->prev == head; } /** @@ -101,8 +107,9 @@ static inline int list_is_first(const struct list_head *list, const struct list_ * @list: the entry to test * @head: the head of the list */ -static inline int list_is_last(const struct list_head *list, const struct list_head *head) { - return list->next == head; +static inline int list_is_last(const struct list_head *list, + const struct list_head *head) { + return list->next == head; } /** @@ -110,8 +117,9 @@ static inline int list_is_last(const struct list_head *list, const struct list_h * @list: the entry to test * @head: the head of the list */ -static inline int list_is_head(const struct list_head *list, const struct list_head *head) { - return list == head; +static inline int list_is_head(const struct list_head *list, + const struct list_head *head) { + return list == head; } /** @@ -119,7 +127,7 @@ static inline int list_is_head(const struct list_head *list, const struct list_h * @head: the list to test. */ static inline int list_empty(const struct list_head *head) { - return head->next == head; + return head->next == head; } /** @@ -127,16 +135,16 @@ static inline int list_empty(const struct list_head *head) { * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next) +#define list_for_each(pos, head) \ + for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next) /** * list_for_each_prev - iterate over a list backwards * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. */ -#define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; !list_is_head(pos, (head)); pos = pos->prev) +#define list_for_each_prev(pos, head) \ + for (pos = (head)->prev; !list_is_head(pos, (head)); pos = pos->prev) /** * list sort @@ -146,8 +154,8 @@ static inline int list_empty(const struct list_head *head) { */ #ifdef HAVE_KLIST_SORT -typedef int (*list_cmp_func_t)(void *, - const struct list_head *, const struct list_head *); +typedef int (*list_cmp_func_t)(void *, const struct list_head *, + const struct list_head *); static void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp); #endif diff --git a/runtime/libutils/include/libutils.h b/runtime/libutils/include/libutils.h index eb490aa..af9b2bc 100644 --- a/runtime/libutils/include/libutils.h +++ b/runtime/libutils/include/libutils.h @@ -1,11 +1,10 @@ #ifndef __SMCC_UTILS_H__ -#define __SMCC_UTILS_H__ +#define __SMCC_UTILS_H__ -#include -#include "vector.h" -#include "kllist.h" #include "hashtable.h" +#include "kllist.h" #include "string.h" #include "strpool.h" +#include #endif // __SMCC_UTILS_H__ diff --git a/runtime/libutils/include/strpool.h b/runtime/libutils/include/strpool.h index 451acc0..39db64d 100644 --- a/runtime/libutils/include/strpool.h +++ b/runtime/libutils/include/strpool.h @@ -1,51 +1,51 @@ /** * @file strpool.h * @brief 字符串池实现 - * + * * 提供字符串驻留(String Interning)功能,保证相同字符串的唯一性存储 */ #ifndef __SMCC_STRPOOL_H__ #define __SMCC_STRPOOL_H__ -#include #include "hashtable.h" #include "string.h" +#include /** * @struct strpool_t * @brief 字符串池上下文 - * + * * 组合哈希表和专用内存分配器实现的高效字符串存储池 */ typedef struct strpool { - hash_table_t ht; /**< 哈希表用于快速查找已存储字符串 */ + hash_table_t ht; /**< 哈希表用于快速查找已存储字符串 */ } strpool_t; /** * @brief 初始化字符串池 * @param pool 字符串池实例指针 */ -void init_strpool(strpool_t* pool); +void init_strpool(strpool_t *pool); /** * @brief 驻留字符串到池中 * @param pool 字符串池实例指针 * @param str 要驻留的 C 字符串 * @return 池中唯一字符串的持久指针 - * + * * @note 返回值生命周期与字符串池一致 * @note 重复插入相同字符串会返回已有指针 */ -const char* strpool_intern(strpool_t* pool, const char* str); +const char *strpool_intern(strpool_t *pool, const char *str); /** * @brief 销毁字符串池 * @param pool 字符串池实例指针 - * + * * @warning 销毁后已获取的字符串指针将失效 * @note 会自动释放所有驻留字符串内存 */ -void strpool_destroy(strpool_t* pool); +void strpool_destroy(strpool_t *pool); #endif // __SMCC_STRPOOL_H__ diff --git a/runtime/libutils/include/vector.h b/runtime/libutils/include/vector.h deleted file mode 100644 index 5464d7a..0000000 --- a/runtime/libutils/include/vector.h +++ /dev/null @@ -1,119 +0,0 @@ -/** - * @file vector.h - * @brief 动态数组(Vector)实现 - * - * 提供类型安全的动态数组容器实现,支持自动扩容和基本操作 - */ - -#ifndef __SMCC_DS_VECTOR_H__ -#define __SMCC_DS_VECTOR_H__ - -#include - -#define __vec_realloc smcc_realloc -#define __vec_free smcc_free - -/** @defgroup vector_struct 数据结构定义 */ - -/** - * @def VECTOR_HEADER(name, type) - * @brief 声明向量结构体 - * @param name 结构体变量名 - * @param type 存储的数据类型 - * - * 生成包含size/cap/data三个字段的结构体定义: - * - size: 当前元素数量 - * - cap: 数组容量 - * - data: 存储数组指针 - */ -#define VECTOR_HEADER(name, type) \ - struct { \ - isize size; /**< 当前元素数量 */ \ - isize cap; /**< 数组容量 */ \ - type *data; /**< 数据存储指针 */ \ - } name - -/** @defgroup vector_operations 向量操作宏 */ - -/** - * @def vector_init(vec) - * @brief 初始化向量结构体 - * @param vec 要初始化的向量结构体变量 - * - * @note 此宏不会分配内存,仅做零初始化 - */ -#define vector_init(vec) \ - do { \ - (vec).size = 0, \ - (vec).cap = 0, \ - (vec).data = 0; \ - } while(0) - -/** - * @def vector_push(vec, value) - * @brief 添加元素到向量末尾 - * @param vec 目标向量结构体 - * @param value 要添加的值(需匹配存储类型) - * - * @note 当容量不足时自动扩容为2倍(初始容量为8) - * @warning 内存分配失败时会触发LOG_FATAL - */ -#define vector_push(vec, value) \ - do { \ - if (vec.size >= vec.cap) { \ - int cap = vec.cap ? vec.cap * 2 : 8; \ - void* data = __vec_realloc(vec.data, cap * sizeof(*vec.data)); \ - if (!data) { \ - LOG_FATAL("vector_push: rt_realloc failed\n"); \ - } \ - (vec).cap = cap; \ - (vec).data = data; \ - } \ - (vec).data[(vec).size++] = value; \ - } while(0) - -/** - * @def vector_pop(vec) - * @brief 弹出最后一个元素 - * @param vec 目标向量结构体 - * @return 最后元素的引用 - * @warning 需确保size > 0时使用 - */ -#define vector_pop(vec) \ - ((vec).data[--(vec).size]) - -/** - * @def vector_at(vec, idx) - * @brief 获取指定索引元素 - * @param vec 目标向量结构体 - * @param idx 元素索引(0 <= idx < size) - * @return 对应元素的引用 - */ -#define vector_at(vec, idx) \ - (((vec).data)[idx]) - -/** - * @def vector_idx(vec, ptr) - * @brief 获取元素指针对应的索引 - * @param vec 目标向量结构体 - * @param ptr 元素指针(需在data数组范围内) - * @return 元素索引值 - */ -#define vector_idx(vec, ptr) \ - ((ptr) - (vec).data) - -/** - * @def vector_free(vec) - * @brief 释放向量内存 - * @param vec 目标向量结构体 - * - * @note 释放后需重新初始化才能再次使用 - */ -#define vector_free(vec) \ - do { \ - __vec_free((vec).data); \ - (vec).data = NULL; \ - (vec).size = (vec).cap = 0; \ - } while(0) - -#endif // __SMCC_DS_VECTOR_H__ diff --git a/runtime/libutils/src/hashtable.c b/runtime/libutils/src/hashtable.c index cc442cf..654825e 100644 --- a/runtime/libutils/src/hashtable.c +++ b/runtime/libutils/src/hashtable.c @@ -2,7 +2,7 @@ #define INIT_HASH_TABLE_SIZE (32) -void init_hashtable(hash_table_t* ht) { +void init_hashtable(hash_table_t *ht) { vector_init(ht->entries); ht->count = 0; ht->tombstone_count = 0; @@ -19,36 +19,39 @@ static int next_power_of_two(int n) { return n + 1; } -static hash_entry_t* find_entry(hash_table_t* ht, const void* key, u32 hash) { - if (ht->entries.cap == 0) return NULL; - +static hash_entry_t *find_entry(hash_table_t *ht, const void *key, u32 hash) { + if (ht->entries.cap == 0) + return NULL; + u32 index = hash & (ht->entries.cap - 1); // 容量是2的幂 u32 probe = 0; - hash_entry_t* tombstone = NULL; - + hash_entry_t *tombstone = NULL; + while (1) { - hash_entry_t* entry = &vector_at(ht->entries, index); + hash_entry_t *entry = &vector_at(ht->entries, index); if (entry->state == ENTRY_EMPTY) { return tombstone ? tombstone : entry; } - + if (entry->state == ENTRY_TOMBSTONE) { - if (!tombstone) tombstone = entry; + if (!tombstone) + tombstone = entry; } else if (entry->hash == hash && ht->key_cmp(entry->key, key) == 0) { return entry; } - + // Liner finding index = (index + 1) & (ht->entries.cap - 1); probe++; - if (probe >= ht->entries.cap) break; + if (probe >= ht->entries.cap) + break; } LOG_ERROR("hashset_find: hash table is full"); return NULL; } -static void adjust_capacity(hash_table_t* ht, int new_cap) { +static void adjust_capacity(hash_table_t *ht, int new_cap) { new_cap = next_power_of_two(new_cap); Assert(new_cap >= ht->entries.cap); @@ -64,9 +67,9 @@ static void adjust_capacity(hash_table_t* ht, int new_cap) { // rehash the all of the old data for (usize i = 0; i < old_entries.cap; i++) { - hash_entry_t* entry = &vector_at(old_entries, i); + hash_entry_t *entry = &vector_at(old_entries, i); if (entry->state == ENTRY_ACTIVE) { - hash_entry_t* dest = find_entry(ht, entry->key, entry->hash); + hash_entry_t *dest = find_entry(ht, entry->key, entry->hash); *dest = *entry; } } @@ -75,23 +78,26 @@ static void adjust_capacity(hash_table_t* ht, int new_cap) { ht->tombstone_count = 0; } -void* hashtable_set(hash_table_t* ht, const void* key, void* value) { +void *hashtable_set(hash_table_t *ht, const void *key, void *value) { if (ht->count + ht->tombstone_count >= ht->entries.cap * 0.75) { - int new_cap = ht->entries.cap < INIT_HASH_TABLE_SIZE ? INIT_HASH_TABLE_SIZE : ht->entries.cap * 2; + int new_cap = ht->entries.cap < INIT_HASH_TABLE_SIZE + ? INIT_HASH_TABLE_SIZE + : ht->entries.cap * 2; adjust_capacity(ht, new_cap); } u32 hash = ht->hash_func(key); - hash_entry_t* entry = find_entry(ht, key, hash); - - void* old_value = NULL; + hash_entry_t *entry = find_entry(ht, key, hash); + + void *old_value = NULL; if (entry->state == ENTRY_ACTIVE) { old_value = entry->value; } else { - if (entry->state == ENTRY_TOMBSTONE) ht->tombstone_count--; + if (entry->state == ENTRY_TOMBSTONE) + ht->tombstone_count--; ht->count++; } - + entry->key = key; entry->value = value; entry->hash = hash; @@ -99,38 +105,42 @@ void* hashtable_set(hash_table_t* ht, const void* key, void* value) { return old_value; } -void* hashtable_get(hash_table_t* ht, const void* key) { - if (ht->entries.cap == 0) return NULL; - +void *hashtable_get(hash_table_t *ht, const void *key) { + if (ht->entries.cap == 0) + return NULL; + u32 hash = ht->hash_func(key); - hash_entry_t* entry = find_entry(ht, key, hash); + hash_entry_t *entry = find_entry(ht, key, hash); return (entry && entry->state == ENTRY_ACTIVE) ? entry->value : NULL; } -void* hashtable_del(hash_table_t* ht, const void* key) { - if (ht->entries.cap == 0) return NULL; - +void *hashtable_del(hash_table_t *ht, const void *key) { + if (ht->entries.cap == 0) + return NULL; + u32 hash = ht->hash_func(key); - hash_entry_t* entry = find_entry(ht, key, hash); - - if (entry == NULL || entry->state != ENTRY_ACTIVE) return NULL; - - void* value = entry->value; + hash_entry_t *entry = find_entry(ht, key, hash); + + if (entry == NULL || entry->state != ENTRY_ACTIVE) + return NULL; + + void *value = entry->value; entry->state = ENTRY_TOMBSTONE; ht->count--; ht->tombstone_count++; return value; } -void hashtable_destory(hash_table_t* ht) { +void hashtable_destory(hash_table_t *ht) { vector_free(ht->entries); ht->count = 0; ht->tombstone_count = 0; } -void hashtable_foreach(hash_table_t* ht, hash_table_iter_func iter_func, void* context) { +void hashtable_foreach(hash_table_t *ht, hash_table_iter_func iter_func, + void *context) { for (usize i = 0; i < ht->entries.cap; i++) { - hash_entry_t* entry = &vector_at(ht->entries, i); + hash_entry_t *entry = &vector_at(ht->entries, i); if (entry->state == ENTRY_ACTIVE) { if (!iter_func(entry->key, entry->value, context)) { break; // enable callback function terminal the iter diff --git a/runtime/libutils/src/strpool.c b/runtime/libutils/src/strpool.c index ca9369d..d17aa20 100644 --- a/runtime/libutils/src/strpool.c +++ b/runtime/libutils/src/strpool.c @@ -1,6 +1,6 @@ #include "strpool.h" -u32 rt_strhash(const char* s) { +u32 rt_strhash(const char *s) { u32 hash = 2166136261u; // FNV-1a偏移基础值 while (*s) { hash ^= *s++; @@ -9,7 +9,7 @@ u32 rt_strhash(const char* s) { return hash; } -int rt_strcmp(const char* s1, const char* s2) { +int rt_strcmp(const char *s1, const char *s2) { while (*s1 && *s2 && *s1 == *s2) { s1++; s2++; @@ -17,20 +17,20 @@ int rt_strcmp(const char* s1, const char* s2) { return *s1 - *s2; } -void init_strpool(strpool_t* pool) { - pool->ht.hash_func = (u32(*)(const void*))rt_strhash; - pool->ht.key_cmp = (int(*)(const void*, const void*))rt_strcmp; +void init_strpool(strpool_t *pool) { + pool->ht.hash_func = (u32 (*)(const void *))rt_strhash; + pool->ht.key_cmp = (int (*)(const void *, const void *))rt_strcmp; init_hashtable(&pool->ht); } -const char* strpool_intern(strpool_t* pool, const char* str) { - void* existing = hashtable_get(&pool->ht, str); +const char *strpool_intern(strpool_t *pool, const char *str) { + void *existing = hashtable_get(&pool->ht, str); if (existing) { return existing; } rt_size_t len = rt_strlen(str) + 1; - char* new_str = lalloc_alloc(&pool->stralloc, len); + char *new_str = lalloc_alloc(&pool->stralloc, len); if (!new_str) { LOG_ERROR("strpool: Failed to allocate memory for string"); return NULL; @@ -41,7 +41,7 @@ const char* strpool_intern(strpool_t* pool, const char* str) { return new_str; } -void strpool_destroy(strpool_t* pool) { +void strpool_destroy(strpool_t *pool) { hashtable_destory(&pool->ht); lalloc_destroy(&pool->stralloc); } diff --git a/runtime/log/include/color.h b/runtime/log/include/color.h index 71f65f4..2930303 100644 --- a/runtime/log/include/color.h +++ b/runtime/log/include/color.h @@ -1,13 +1,14 @@ /** * @file color.h * @brief ANSI终端颜色控制码定义 - * + * * 提供跨平台的终端文本颜色和样式控制支持 */ #ifndef __SMCC_TERMINAL_COLOR_H__ #define __SMCC_TERMINAL_COLOR_H__ +/* clang-format off */ /// @name 前景色控制码 /// @{ #define ANSI_FG_BLACK "\33[30m" ///< 黑色前景 @@ -38,22 +39,23 @@ #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 ///< 启用样式包裹 +#define ANSI_FMT(str, fmt) fmt str ANSI_NONE ///< 启用样式包裹 #else -#define ANSI_FMT(str, fmt) str ///< 禁用样式输出 +#define ANSI_FMT(str, fmt) str ///< 禁用样式输出 #endif #endif // __SMCC_TERMINAL_COLOR_H__ diff --git a/runtime/log/include/log.c b/runtime/log/include/log.c index b48998a..d9cbd00 100644 --- a/runtime/log/include/log.c +++ b/runtime/log/include/log.c @@ -1,35 +1,62 @@ #include -void log_default_handler(log_level_t level, const char* module, const char* file, int line, const char* message) { - const char* level_str; +void log_default_handler(log_level_t level, const char *module, + const char *file, int line, const char *message) { + const char *level_str; 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; + 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; + 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; + 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; } log_printf(ANSI_BOLD "%s[%s] - %s - %s:%d | %s" ANSI_NONE "\n", color_code, - level_str, module, file, line, message); + level_str, module, file, line, message); #else - log_printf("[%s] %s:%d | %s: %s\n", - level_str, file, line, module, message); + log_printf("[%s] %s:%d | %s: %s\n", level_str, file, line, module, message); #endif // for clangd warning // clang-analyzer-deadcode.DeadStores @@ -46,26 +73,26 @@ logger_t logger_root = { .handler = log_default_handler, }; -void init_logger(logger_t* logger, const char* name) { +void init_logger(logger_t *logger, const char *name) { logger->name = name; logger->handler = log_default_handler; log_set_level(logger, LOG_LEVEL_ALL); } -logger_t* log_get(const char* name) { - return &logger_root; +logger_t *log_get(const char *name) { return &logger_root; } + +void log_set_level(logger_t *logger, int level) { + if (logger) + logger->level = level; + else + logger_root.level = level; } -void log_set_level(logger_t* logger, int level) { - if (logger) logger->level = level; - else logger_root.level = level; +void log_set_handler(logger_t *logger, log_handler handler) { + if (logger) + logger->handler = handler; + else + logger_root.handler = handler; } -void log_set_handler(logger_t* logger, log_handler handler) { - if (logger) logger->handler = handler; - else logger_root.handler = handler; -} - -void logger_destroy(logger_t* logger) { - return; -} +void logger_destroy(logger_t *logger) { return; } diff --git a/runtime/log/include/log.h b/runtime/log/include/log.h index 03b8dbf..456b7a1 100644 --- a/runtime/log/include/log.h +++ b/runtime/log/include/log.h @@ -33,18 +33,18 @@ /** * @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_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; /** @@ -56,31 +56,27 @@ typedef enum log_level { * @param message 格式化后的日志消息 * @todo 待实现模块名称,输入的模块名称,都将被忽略 */ -typedef void (*log_handler)( - log_level_t level, - const char* module, - const char* file, - int line, - const char* message -); +typedef void (*log_handler)(log_level_t level, const char *module, + const char *file, int line, const char *message); #ifndef LOGGER_MAX_BUF_SIZE -#define LOGGER_MAX_BUF_SIZE 512 ///< 单条日志最大缓冲区尺寸 +#define LOGGER_MAX_BUF_SIZE 512 ///< 单条日志最大缓冲区尺寸 #endif /** * @brief 日志器实例结构体 - * + * * 每个日志器实例维护独立的配置和缓冲区 */ typedef struct logger { - const char* name; ///< 日志器名称(用于模块区分) - log_level_t level; ///< 当前设置的日志级别 - log_handler handler; ///< 日志处理回调函数 + const char *name; ///< 日志器名称(用于模块区分) + log_level_t level; ///< 当前设置的日志级别 + log_handler handler; ///< 日志处理回调函数 char buf[LOGGER_MAX_BUF_SIZE]; ///< 格式化缓冲区 } logger_t; -void log_default_handler(log_level_t level, const char* module, const char* file, int line, const char* message); +void log_default_handler(log_level_t level, const char *module, + const char *file, int line, const char *message); extern logger_t logger_root; /** @@ -88,7 +84,7 @@ extern logger_t logger_root; * @param[in] logger 日志器实例指针 * @param[in] name 日志器名称(NULL表示获取默认日志器名称) */ -void init_logger(logger_t* logger, const char* name); +void init_logger(logger_t *logger, const char *name); // TODO log_set(); 暂未实现 日志注册 @@ -98,29 +94,29 @@ void init_logger(logger_t* logger, const char* name); * @return 日志器实例指针 * @warning 若没有找到相应日志器则会返回根日志器 */ -logger_t* log_get(const char* name); +logger_t *log_get(const char *name); /** * @brief 设置日志级别 * @param[in] logger 目标日志器实例 * @param[in] level 要设置的日志级别(可组合多个级别) */ -void log_set_level(logger_t* logger, int level); +void log_set_level(logger_t *logger, int level); /** * @brief 设置自定义日志处理器 * @param[in] logger 目标日志器实例 * @param[in] handler 自定义处理函数(NULL恢复默认处理) */ -void log_set_handler(logger_t* logger, log_handler handler); +void log_set_handler(logger_t *logger, log_handler handler); /** * @todo TODO impliment */ -void logger_destroy(logger_t* logger); +void logger_destroy(logger_t *logger); #ifndef LOG_MAX_MAROC_BUF_SIZE -#define LOG_MAX_MAROC_BUF_SIZE LOGGER_MAX_BUF_SIZE ///< 宏展开缓冲区尺寸 +#define LOG_MAX_MAROC_BUF_SIZE LOGGER_MAX_BUF_SIZE ///< 宏展开缓冲区尺寸 #endif /** @@ -131,39 +127,55 @@ void logger_destroy(logger_t* logger); * @param _msg_ 格式字符串 * @param ... 可变参数列表 */ -#define _LOG(_module_, _level_, _msg_, ...) \ - do { \ - logger_t* _logger; \ - if (!_module_) { \ - _logger = log_get(NULL); \ - } \ - else _logger = _module_; \ - if (_logger && _logger->handler && (_logger->level & (_level_))) { \ - log_snprintf(_logger->buf, sizeof(_logger->buf), (_msg_), ##__VA_ARGS__); \ - _logger->handler((_level_), _logger->name, __FILE__, __LINE__, _logger->buf); \ - } \ - } while(0) +#define _LOG(_module_, _level_, _msg_, ...) \ + do { \ + logger_t *_logger; \ + if (!_module_) { \ + _logger = log_get(NULL); \ + } else \ + _logger = _module_; \ + if (_logger && _logger->handler && (_logger->level & (_level_))) { \ + log_snprintf(_logger->buf, sizeof(_logger->buf), (_msg_), \ + ##__VA_ARGS__); \ + _logger->handler((_level_), _logger->name, __FILE__, __LINE__, \ + _logger->buf); \ + } \ + } while (0) /// @name 模块日志宏 /// @{ -#define MLOG_NOTSET(module, ...) _LOG(module, LOG_LEVEL_NOTSET, __VA_ARGS__) ///< 未分类日志 -#define MLOG_DEBUG( module, ...) _LOG(module, LOG_LEVEL_DEBUG, __VA_ARGS__) ///< 调试日志(需启用DEBUG级别) -#define MLOG_INFO( module, ...) _LOG(module, LOG_LEVEL_INFO, __VA_ARGS__) ///< 信息日志(常规运行日志) -#define MLOG_WARN( module, ...) _LOG(module, LOG_LEVEL_WARN, __VA_ARGS__) ///< 警告日志(潜在问题) -#define MLOG_ERROR( module, ...) _LOG(module, LOG_LEVEL_ERROR, __VA_ARGS__) ///< 错误日志(可恢复错误) -#define MLOG_FATAL( module, ...) _LOG(module, LOG_LEVEL_FATAL, __VA_ARGS__) ///< 致命错误日志(程序终止前) -#define MLOG_TRACE( module, ...) _LOG(module, LOG_LEVEL_TRACE, __VA_ARGS__) ///< 追踪日志(调用栈跟踪) +#define MLOG_NOTSET(module, ...) \ + _LOG(module, LOG_LEVEL_NOTSET, __VA_ARGS__) ///< 未分类日志 +#define MLOG_DEBUG(module, ...) \ + _LOG(module, LOG_LEVEL_DEBUG, __VA_ARGS__) ///< 调试日志(需启用DEBUG级别) +#define MLOG_INFO(module, ...) \ + _LOG(module, LOG_LEVEL_INFO, __VA_ARGS__) ///< 信息日志(常规运行日志) +#define MLOG_WARN(module, ...) \ + _LOG(module, LOG_LEVEL_WARN, __VA_ARGS__) ///< 警告日志(潜在问题) +#define MLOG_ERROR(module, ...) \ + _LOG(module, LOG_LEVEL_ERROR, __VA_ARGS__) ///< 错误日志(可恢复错误) +#define MLOG_FATAL(module, ...) \ + _LOG(module, LOG_LEVEL_FATAL, __VA_ARGS__) ///< 致命错误日志(程序终止前) +#define MLOG_TRACE(module, ...) \ + _LOG(module, LOG_LEVEL_TRACE, __VA_ARGS__) ///< 追踪日志(调用栈跟踪) /// @} /// @name 快捷日志宏 /// @{ -#define LOG_NOTSET(...) _LOG(NULL, LOG_LEVEL_NOTSET, __VA_ARGS__) ///< 未分类日志 -#define LOG_DEBUG(...) _LOG(NULL, LOG_LEVEL_DEBUG, __VA_ARGS__) ///< 调试日志(需启用DEBUG级别) -#define LOG_INFO(...) _LOG(NULL, LOG_LEVEL_INFO, __VA_ARGS__) ///< 信息日志(常规运行日志) -#define LOG_WARN(...) _LOG(NULL, LOG_LEVEL_WARN, __VA_ARGS__) ///< 警告日志(潜在问题) -#define LOG_ERROR(...) _LOG(NULL, LOG_LEVEL_ERROR, __VA_ARGS__) ///< 错误日志(可恢复错误) -#define LOG_FATAL(...) _LOG(NULL, LOG_LEVEL_FATAL, __VA_ARGS__) ///< 致命错误日志(程序终止前) -#define LOG_TRACE(...) _LOG(NULL, LOG_LEVEL_TRACE, __VA_ARGS__) ///< 追踪日志(调用栈跟踪) +#define LOG_NOTSET(...) \ + _LOG(NULL, LOG_LEVEL_NOTSET, __VA_ARGS__) ///< 未分类日志 +#define LOG_DEBUG(...) \ + _LOG(NULL, LOG_LEVEL_DEBUG, __VA_ARGS__) ///< 调试日志(需启用DEBUG级别) +#define LOG_INFO(...) \ + _LOG(NULL, LOG_LEVEL_INFO, __VA_ARGS__) ///< 信息日志(常规运行日志) +#define LOG_WARN(...) \ + _LOG(NULL, LOG_LEVEL_WARN, __VA_ARGS__) ///< 警告日志(潜在问题) +#define LOG_ERROR(...) \ + _LOG(NULL, LOG_LEVEL_ERROR, __VA_ARGS__) ///< 错误日志(可恢复错误) +#define LOG_FATAL(...) \ + _LOG(NULL, LOG_LEVEL_FATAL, __VA_ARGS__) ///< 致命错误日志(程序终止前) +#define LOG_TRACE(...) \ + _LOG(NULL, LOG_LEVEL_TRACE, __VA_ARGS__) ///< 追踪日志(调用栈跟踪) /// @} /** @@ -172,24 +184,30 @@ void logger_destroy(logger_t* logger); * @param cond 检查条件表达式 * @param ... 错误信息参数(格式字符串+参数) */ -#define _Assert(cond, ...) \ - do { \ - if (!(cond)) { \ - LOG_FATAL(__VA_ARGS__); \ - } \ +#define _Assert(cond, ...) \ + do { \ + if (!(cond)) { \ + LOG_FATAL(__VA_ARGS__); \ + } \ } while (0) /// @name 断言工具宏 /// @{ #define __INNER_LOG_STR(str) #str #define __LOG_STR(str) __INNER_LOG_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 `" __LOG_STR(cond) "`") ///< 基础断言检查 +#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 `" __LOG_STR(cond) "`") ///< 基础断言检查 #define Panic(...) PanicFmt(__VA_ARGS__) ///< 触发致命错误(带自定义消息) -#define TODO() PanicFmt("TODO please implement me") ///< 标记未实现代码(触发致命错误) +#define TODO() \ + PanicFmt("TODO please implement me") ///< 标记未实现代码(触发致命错误) #define UNREACHABLE() PanicFmt("UNREACHABLE") ///< 触发致命错误(代码不可达) -#define FIXME(str) PanicFmt("FIXME " __LOG_STR(str)) ///< 提醒开发者修改代码(触发致命错误) +#define FIXME(str) \ + PanicFmt("FIXME " __LOG_STR(str)) ///< 提醒开发者修改代码(触发致命错误) /// @} #ifdef __SMCC_LOG_IMPORT_SRC__