dtl v0.3 Alpha

This commit is contained in:
rangersly 2025-06-01 21:17:47 +08:00
commit 854b8ac278
4 changed files with 400 additions and 0 deletions

119
dtl.h Normal file
View File

@ -0,0 +1,119 @@
/*
Copyright(c) 2025 Rangersly All rights reserved.
DEBUG TOOLS
Version: v0.1-Alpha
v0.1-Beta
v0.2-Alpha
v0.3-Alpha
*/
#ifndef DEBUGTOOLS
#define DEBUGTOOLS
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
/* 一些基础调试函数 */
#ifdef DEBUG
/* 字符串检查宏,输出字符串的每一位数据 */
#define print_str(str, len) do{ \
size_t _len = (size_t)len; \
printf("%s\n", str); \
for(int i = 0; i < _len; i++) \
printf("%2x -- %c\n", i, (char)str[i], (uint8_t)str[i]); \
}while(0)
/* 输出调试错误报错信息,辅助定位错误地点 */
#define PERROR(str) printf("%s:%d:%s:\n%s\n", __FILE__, __LINE__, __func__, str); exit(0)
#else
#define print_str(str, len)
#define PERROR(str)
#endif
/*----------------------------------------------*/
/* 内存函数重封装 */
#ifdef DEBUG
/* 显示当前的内存情况 */
#define display_memory_status() __display_memory_status()
/* 重封装malloc函数,第二个参数是内存块说明 */
#define _malloc(size, message) __malloc(size, message)
/* 重封装free */
#define _free(point) __free(point)
#else
/* 非调试版本 */
#define display_memory_status()
#define _malloc(size, message) malloc(size)
#define _free(point) free(point)
#endif
struct Memory_info {
size_t size; /* 内存块大小 */
struct Memory_info *next; /* 下一个内存块 */
void *address; /* 内存块地址 */
char message[32]; /* 内存块信息 */
};
struct Memory_status {
size_t all_size; /* 使用的内存总大小 */
int count; /* 当前内存块个数 */
struct Memory_info *front; /* 存储信息头部 */
};
void*
__malloc(size_t size, const char *a);
void
__free(void *ptr);
void
__display_memory_status(void);
/*----------------------------------------------*/
/* 日志系统 */
enum LOG_LEVEL{
LOG_INFO = 0,
LOG_WARNING = 1,
LOG_ERROR = 2,
LOG_FATAL = 3
};
/* 最大日志头长度 */
#define LOG_HEAD_MAX_FORMAT 32
/* 设置日志输出 */
void
log_setoutfile(const char *restrict filename);
/* 设置日志的最低输出等级 */
void
log_setlevel(enum LOG_LEVEL level);
/* 设置日志头,最大不可超过15个字符 */
void
log_sethead(const char *restrict head);
/*
*
* %Y year
* %M month
* %d day
* %h hour
* %m minute
* %s second
* %n number
* %c core time .3f
*/
/* 输出日志,包含日志等级与日志信息 */
void
log_print(enum LOG_LEVEL level, const char *restrict message);
/*----------------------------------------------*/
#endif

137
log-dtl.c Normal file
View File

@ -0,0 +1,137 @@
#include "dtl.h"
#include <time.h>
#include <string.h>
static enum LOG_LEVEL low_show_level = LOG_INFO;
static uint32_t log_number = 1;
static FILE *log_out_fp = NULL;
static char log_head_format[LOG_HEAD_MAX_FORMAT] = "[%y-%m-%d-%n]";
static char log_head[LOG_HEAD_MAX_FORMAT << 3];
/*
*
*
* Description:
* log_head_format中的特殊符号
* ret 0 -> success
* ret !0 -> Unrecognized symbol
*/
static void
get_loghead(void);
static void
int_to_str(char *restrict dst, uint32_t num, size_t n);
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
void
log_setoutfile(const char *restrict filename)
{
if((log_out_fp = fopen(filename, "w")) == NULL)
perror("log-dtl.c:log_setoutfile: Failed to open file !\n");
}
void
log_setlevel(enum LOG_LEVEL level) {
if(level < LOG_INFO || level > LOG_FATAL)
low_show_level = LOG_INFO;
else
low_show_level = level;
}
void
log_sethead(const char *restrict head) {
if(strlen(head) >= LOG_HEAD_MAX_FORMAT)
return;
strncpy(log_head_format, head, LOG_HEAD_MAX_FORMAT);
}
void
log_print(enum LOG_LEVEL level, const char *restrict message) {
if(log_out_fp == NULL)
log_out_fp = stdout;
if(level < low_show_level)
return;
get_loghead();
fputs(log_head, log_out_fp);
switch(level) { // 打印错误等级
case LOG_INFO:
fputs("INFO:", log_out_fp);break;
case LOG_WARNING:
fputs("WARNING:", log_out_fp);break;
case LOG_ERROR:
fputs("ERROR:", log_out_fp);break;
case LOG_FATAL:
fputs("FATAL:", log_out_fp);break;
}
fputs(message, log_out_fp);
fputc('\n', log_out_fp);
log_number++; // 日志计数++
}
void
get_loghead(void) {
char buf[32];
time_t now_time = time(NULL);
clock_t core_time = clock() / CLOCKS_PER_SEC;
struct tm *tm_time = localtime(&now_time);
memset(log_head, '\0', sizeof(log_head));
for(int i = 0; i < strlen(log_head_format); i++) {
if(log_head_format[i] != '%') {
log_head[strlen(log_head)] = log_head_format[i];
continue;
}
i++;
switch(log_head_format[i]) { // 特殊字符转换
case 'Y':
strftime(buf, 32, "%Y", tm_time);break;
case 'M':
strftime(buf, 32, "%m", tm_time);break;
case 'd':
strftime(buf, 32, "%d", tm_time);break;
case 'h':
strftime(buf, 32, "%H", tm_time);break;
case 'm':
strftime(buf, 32, "%M", tm_time);break;
case 's':
strftime(buf, 32, "%S", tm_time);break;
case 'n':
int_to_str(buf, log_number, 32);break;
case 'c':
int_to_str(buf, core_time, 32);break;
default:
strcpy(buf, "!!");
}
strcat(log_head, buf);
}
}
void
int_to_str(char *restrict dst, uint32_t num, size_t n) {
// 逐位提取数字(反向存储)
int start = 0;
do {
dst[start++] = num % 10 + '0';
num /= 10;
} while (num > 0);
dst[start] = '\0';
// 反转数字部分
char buf[16];
strncpy(buf, dst, 15);
for(int i = 0; i < strlen(buf); i++)
dst[--start] = buf[i];
}

32
makefile Normal file
View File

@ -0,0 +1,32 @@
# 编译器与工具配置
CC := gcc
AR := ar
CFLAGS := -Wall -O2 -fPIC -MMD # 启用优化、位置无关代码和依赖生成
ARFLAGS := rcs # 静态库打包选项
# 文件与目标
SRC := $(wildcard *.c) # 所有源文件
OBJS := $(patsubst %.c,%.o,$(SRC)) # 目标文件
DEPS := $(OBJS:.o=.d) # 依赖文件
TARGET := libdtl.a # 最终库文件
# 默认目标
all: $(TARGET)
# 生成静态库
$(TARGET): $(OBJS)
$(AR) $(ARFLAGS) $@ $^
# 编译目标文件(支持多线程)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
# 包含自动生成的依赖文件
-include $(DEPS)
# 清理
clean:
rm -f $(OBJS) $(DEPS) $(TARGET)
# 声明伪目标
.PHONY: all clean

112
mem-dtl.c Normal file
View File

@ -0,0 +1,112 @@
#include <error.h>
#include <string.h>
#include "dtl.h"
/* Memory_info 结构 伪构造函数 */
static struct Memory_info *
memory_info_init(size_t size, struct Memory_info *next, const char *a);
/* Memory_status 结构初始化函数 */
static void
memory_status_init(void);
static struct Memory_status memory_status_dbtools = {0, 0, NULL};
void
memory_status_init(void)
{
memory_status_dbtools.all_size = 0;
memory_status_dbtools.count = 0;
memory_status_dbtools.front = memory_info_init(0, NULL, "root");
}
void*
__malloc(size_t size, const char *a)
{
/* 确保已经初始化 */
if(memory_status_dbtools.front == NULL)
memory_status_init();
struct Memory_info *it = memory_status_dbtools.front;
/* 寻找不大于当前内存块的第一个位置 */
while((it->next != NULL) && (it->next->size > size))
it = it->next;
/* 分配内存块 */
it->next = memory_info_init(size, it->next, a);
/* 分配成功 修改总数据 */
memory_status_dbtools.all_size += size;
memory_status_dbtools.count++;
return it->next->address;
}
void
__free(void *ptr)
{
/* 避免释放不存在的内存 */
if(NULL == ptr)
return;
/* 确保已经初始化 */
if(memory_status_dbtools.front == NULL)
memory_status_init();
struct Memory_info *it = memory_status_dbtools.front;
while(it->next != NULL) {
/* 找到对应的地址块信息就在信息链表中删除 */
if(ptr == it->next->address) {
struct Memory_info *temp = it->next->next;
memory_status_dbtools.all_size -= it->next->size;
memory_status_dbtools.count--;
free(ptr);
ptr = NULL;
free(it->next);
it->next = temp;
break;
}
it = it->next;
}
}
extern void
__display_memory_status(void)
{
printf("\n---Memory status---\n");
printf("All_size: %ld\n", memory_status_dbtools.all_size);
printf("count: %d\n", memory_status_dbtools.count);
printf("--- Stat Info ---\n");
struct Memory_info *it = memory_status_dbtools.front->next;
while(NULL != it) {
printf("%p\n", it->address);
printf("%ld\n", it->size);
printf(it->message);
printf("\n----------------\n");
it = it->next;
}
printf("\n\n");
}
struct Memory_info *
memory_info_init(size_t size, struct Memory_info *next, const char *a)
{
struct Memory_info *dst;
dst = (struct Memory_info*)malloc(sizeof(struct Memory_info));
if(NULL == dst)
perror("memory_info_init: malloc fail!");
dst->size = size;
dst->next = next;
if(size != 0) {
dst->address = malloc(size);
if(NULL == dst->address)
perror("memory_info_init: malloc fail!");
} else dst->address = NULL;
strncpy(dst->message, a, 31);
return dst;
}