feat: 新增安全字符串处理和日志系统模块

- 添加 safe_string 模块,提供安全的字符串复制、拼接和复制功能
- 添加 logger 模块,支持多级别日志记录和文件输出
- 添加 error_code 模块,定义统一的错误代码枚举
- 添加 layout_config 模块,定义布局配置结构
- 更新 CMakeLists.txt 包含新增的源文件
This commit is contained in:
2026-03-26 12:47:44 +08:00
parent 8767271e96
commit d934d21323
7 changed files with 263 additions and 0 deletions
+2
View File
@@ -14,6 +14,8 @@ set(SOURCES
src/main.c src/main.c
src/utils/string_ext.c src/utils/string_ext.c
src/utils/os_env.c src/utils/os_env.c
src/utils/safe_string.c
src/utils/logger.c
src/ui/ui_utils.c src/ui/ui_utils.c
src/ui/dialogs.c src/ui/dialogs.c
src/ui/main_window.c src/ui/main_window.c
+19
View File
@@ -0,0 +1,19 @@
#ifndef LAYOUT_CONFIG_H
#define LAYOUT_CONFIG_H
// 布局配置结构体
typedef struct {
int vbox_gap; // 垂直布局间距
int vbox_margin_width; // 垂直布局外边距宽度
int vbox_margin_height; // 垂直布局外边距高度
int hbox_gap; // 水平布局间距
int hbox_margin_width; // 水平布局外边距宽度
int hbox_margin_height; // 水平布局外边距高度
int button_width; // 按钮宽度
int button_height; // 按钮高度
} LayoutConfig;
// 默认布局配置
extern const LayoutConfig DEFAULT_LAYOUT;
#endif // LAYOUT_CONFIG_H
+19
View File
@@ -0,0 +1,19 @@
#ifndef ERROR_CODE_H
#define ERROR_CODE_H
typedef enum {
ERR_OK = 0, // 成功
ERR_FAILED = -1, // 失败
ERR_NULL_PTR = -2, // 空指针
ERR_OUT_OF_MEMORY = -3, // 内存不足
ERR_FILE_NOT_FOUND = -4, // 文件不存在
ERR_PERMISSION_DENIED = -5, // 权限拒绝
ERR_INVALID_FORMAT = -6, // 无效格式
ERR_REGISTRY_FAILED = -7, // 注册表操作失败
ERR_NOT_FOUND = -8, // 未找到
ERR_EXISTS = -9 // 已存在
} ErrorCode;
const char* error_code_to_string(ErrorCode code);
#endif // ERROR_CODE_H
+33
View File
@@ -0,0 +1,33 @@
#ifndef LOGGER_H
#define LOGGER_H
// 日志级别
typedef enum {
LOG_LEVEL_DEBUG, // 调试日志级别
LOG_LEVEL_INFO, // 信息日志级别
LOG_LEVEL_WARN, // 警告日志级别
LOG_LEVEL_ERROR // 错误日志级别
} LogLevel;
// 初始化日志系统
void log_init(const char *log_file, LogLevel level);
// 销毁日志系统
void log_destroy(void);
// 日志函数
void log_debug(const char *fmt, ...);
// 信息日志函数
void log_info(const char *fmt, ...);
// 警告日志函数
void log_warn(const char *fmt, ...);
// 错误日志函数
void log_error(const char *fmt, ...);
// 设置日志级别
void log_set_level(LogLevel level);
#endif // LOGGER_H
+15
View File
@@ -0,0 +1,15 @@
#ifndef SAFE_STRING_H
#define SAFE_STRING_H
#include <stddef.h>
// 安全字符串操作函数
char* safe_strcpy(char *dst, size_t dst_size, const char *src);
// 安全字符串拼接函数
char* safe_strcat(char *dst, size_t dst_size, const char *src);
// 安全字符串复制函数
char* safe_strdup(const char *src);
#endif // SAFE_STRING_H
+126
View File
@@ -0,0 +1,126 @@
#include "utils/logger.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
// 全局日志文件指针
static FILE *G_log_file = NULL;
// 全局日志级别
static LogLevel G_log_level = LOG_LEVEL_INFO;
// 将日志级别转换为字符串
static const char *level_to_string(LogLevel level)
{
switch (level)
{
case LOG_LEVEL_DEBUG:
return "DEBUG";
case LOG_LEVEL_INFO:
return "INFO ";
case LOG_LEVEL_WARN:
return "WARN ";
case LOG_LEVEL_ERROR:
return "ERROR";
default:
return "UNKN ";
}
}
// 获取当前时间戳
static void get_timestamp(char *buffer, size_t size)
{
time_t now = time(NULL);
struct tm *tm_info = localtime(&now);
strftime(buffer, size, "%Y-%m-%d %H:%M:%S", tm_info);
}
// 写入日志
static void log_write(LogLevel level, const char *fmt, va_list args)
{
if (level < G_log_level)
return;
char timestamp[64];
get_timestamp(timestamp, sizeof(timestamp));
char message[1024];
vsnprintf(message, sizeof(message), fmt, args);
const char *level_str = level_to_string(level);
if (G_log_file)
{
fprintf(G_log_file, "[%s] [%s] %s\n", timestamp, level_str, message);
fflush(G_log_file);
}
fprintf(stdout, "[%s] [%s] %s\n", timestamp, level_str, message);
}
// 初始化日志系统
void log_init(const char *log_file, LogLevel level)
{
if (log_file)
{
G_log_file = fopen(log_file, "a");
if (!G_log_file)
{
fprintf(stderr, "Failed to open log file: %s\n", log_file);
}
}
G_log_level = level;
}
// 销毁日志系统
void log_destroy(void)
{
if (G_log_file)
{
fclose(G_log_file);
G_log_file = NULL;
}
}
// 设置日志级别
void log_set_level(LogLevel level)
{
G_log_level = level;
}
// 调试日志
void log_debug(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
log_write(LOG_LEVEL_DEBUG, fmt, args);
va_end(args);
}
// 信息日志
void log_info(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
log_write(LOG_LEVEL_INFO, fmt, args);
va_end(args);
}
// 警告日志
void log_warn(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
log_write(LOG_LEVEL_WARN, fmt, args);
va_end(args);
}
// 错误日志
void log_error(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
log_write(LOG_LEVEL_ERROR, fmt, args);
va_end(args);
}
+49
View File
@@ -0,0 +1,49 @@
#include "utils/safe_string.h"
#include <string.h>
#include <stdlib.h>
// 安全字符串复制
char *safe_strcpy(char *dst, size_t dst_size, const char *src)
{
if (!dst || !src || dst_size == 0)
return NULL;
size_t len = strlen(src);
if (len >= dst_size)
{
memcpy(dst, src, dst_size - 1);
dst[dst_size - 1] = '\0';
}
else
{
strcpy(dst, src);
}
return dst;
}
// 安全字符串拼接
char *safe_strcat(char *dst, size_t dst_size, const char *src)
{
if (!dst || !src || dst_size == 0)
return NULL;
size_t dst_len = strlen(dst);
if (dst_len >= dst_size)
return NULL;
return safe_strcpy(dst + dst_len, dst_size - dst_len, src);
}
// 安全字符串复制(返回新分配的内存)
char *safe_strdup(const char *src)
{
if (!src)
return NULL;
size_t len = strlen(src);
char *result = (char *)malloc(len + 1);
if (result)
strcpy(result, src);
return result;
}