merge usingfix
ansi.md fix ADD: pro/tool/makefile add example one FIX: libs.md self log .vimrc fix auto makefile use Tab lib.md string delete
This commit is contained in:
parent
63a85cd79f
commit
e558ee3788
@ -5,7 +5,7 @@
|
|||||||
## index
|
## index
|
||||||
|
|
||||||
- [C](#c)
|
- [C](#c)
|
||||||
- [输入/输出 stdio](#stdio)
|
- [输入/输出 stdio](../universal/io.md)
|
||||||
- [资源管理和系统交互 stdlib](#stdlib)
|
- [资源管理和系统交互 stdlib](#stdlib)
|
||||||
- [字符串处理 string](../universal/cstring.md)
|
- [字符串处理 string](../universal/cstring.md)
|
||||||
- [数学函数 math](#math)
|
- [数学函数 math](#math)
|
||||||
@ -34,12 +34,7 @@
|
|||||||
- [string hash](./self/string_hash.c)
|
- [string hash](./self/string_hash.c)
|
||||||
- [thread pool](./self/thread-pool.cpp)
|
- [thread pool](./self/thread-pool.cpp)
|
||||||
- [BIT](./self/bit.h)
|
- [BIT](./self/bit.h)
|
||||||
|
- [LOG](./self/log/log.h)
|
||||||
---
|
|
||||||
|
|
||||||
## **stdio**
|
|
||||||
|
|
||||||
大部分内容已经完善,请参阅这里[IO](../universal/io.md)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
167
program/c_cpp/library/self/log/log.c
Normal file
167
program/c_cpp/library/self/log/log.c
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#define POINT_STR(str)
|
||||||
|
#define PERROR(str)
|
||||||
|
#else
|
||||||
|
#define POINT_STR(str) for(int i = 0; i < strlen(str); i++) { \
|
||||||
|
printf("%c --- %d\n", (char)str[i], (int)str[i]);}
|
||||||
|
#define PERROR(str) printf(str);return
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int low_show_level = LOG_INFO;
|
||||||
|
static int 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];
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_loghead(void);
|
||||||
|
// 根据 log_head_format 生成日志头 log_head
|
||||||
|
// 有无法识别的符号返回 -1 成功返回0
|
||||||
|
|
||||||
|
static void
|
||||||
|
int_to_str(int num, char *restrict str);
|
||||||
|
// 将int 型数据转换成str
|
||||||
|
// 需要注意 str 要大于 int 的位数,否则将溢出
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
log_setoutfile(const char *restrict filename) {
|
||||||
|
if((log_out_fp = fopen(filename, "w")) == NULL)
|
||||||
|
PERROR("LOG: log_setoutfile open file fail !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
log_setlevel(int level) {
|
||||||
|
if(level < LOG_INFO || level > LOG_FATAL) { // 检测最低日志等级
|
||||||
|
low_show_level = LOG_INFO;
|
||||||
|
PERROR("LOG: log_setlevel level is > LOG_FATAL or < LOG_INFO\n");
|
||||||
|
}
|
||||||
|
low_show_level = level;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
log_sethead(const char *restrict head) {
|
||||||
|
if(strlen(head) >= LOG_HEAD_MAX_FORMAT)
|
||||||
|
PERROR("LOG: log_sethead head so long!\n");
|
||||||
|
strncpy(log_head_format, head, LOG_HEAD_MAX_FORMAT);
|
||||||
|
if(get_loghead())
|
||||||
|
PERROR("LOG: log_sethead have fail char !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
log_print(int level, const char *restrict message) {
|
||||||
|
if(log_out_fp == NULL) // 未设置输出文件
|
||||||
|
log_out_fp = stdout;
|
||||||
|
if(level < LOG_INFO || level > LOG_FATAL) // 日志等级不在范围内
|
||||||
|
PERROR("LOG: log_print level out of range !\n");
|
||||||
|
if(level < low_show_level) // 低于最低等级的log不进行打印
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(get_loghead() != 0) // 生成日志头
|
||||||
|
PERROR("LOG: log_print get_loghead error\n");
|
||||||
|
if(!fputs(log_head, log_out_fp)) // 打印日志头
|
||||||
|
PERROR("LOG: log_print fputs_head error\n");
|
||||||
|
|
||||||
|
switch(level) { // 打印错误等级
|
||||||
|
case LOG_INFO:
|
||||||
|
if(fputs("INFO:", log_out_fp))
|
||||||
|
break;
|
||||||
|
case LOG_WARNING:
|
||||||
|
if(fputs("WARNING:", log_out_fp))
|
||||||
|
break;
|
||||||
|
case LOG_ERROR:
|
||||||
|
if(fputs("ERROR:", log_out_fp))
|
||||||
|
break;
|
||||||
|
case LOG_FATAL:
|
||||||
|
if(fputs("FATAL:", log_out_fp))
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PERROR("LOG: log_print out level is untrue !\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!fputs(message, log_out_fp)) // 打印message
|
||||||
|
PERROR("LOG: log_head fputs fail !\n");
|
||||||
|
fputc('\n', log_out_fp);
|
||||||
|
log_number++; // 日志计数++
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
get_loghead(void) {
|
||||||
|
char buf[64];
|
||||||
|
time_t now_time = time(NULL);
|
||||||
|
clock_t core_time = clock() / CLOCKS_PER_SEC; // 以 s 为单位的 cpu 时间
|
||||||
|
struct tm *tm_time = localtime(&now_time);
|
||||||
|
int temp;
|
||||||
|
|
||||||
|
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, 64, "%Y", tm_time);
|
||||||
|
break;
|
||||||
|
case 'm' :
|
||||||
|
strftime(buf, 64, "%m", tm_time);
|
||||||
|
break;
|
||||||
|
case 'd' :
|
||||||
|
strftime(buf, 64, "%d", tm_time);
|
||||||
|
break;
|
||||||
|
case 'h' :
|
||||||
|
strftime(buf, 64, "%H", tm_time);
|
||||||
|
break;
|
||||||
|
case 'M' :
|
||||||
|
strftime(buf, 64, "%M", tm_time);
|
||||||
|
break;
|
||||||
|
case 's' :
|
||||||
|
strftime(buf, 64, "%S", tm_time);
|
||||||
|
break;
|
||||||
|
case 'n' :
|
||||||
|
int_to_str(log_number, buf);
|
||||||
|
break;
|
||||||
|
case 'c' :
|
||||||
|
int_to_str(core_time, buf);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcat(log_head, buf);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
int_to_str(int num, char *restrict str) {
|
||||||
|
if(num < 0)
|
||||||
|
return; // 日志编号不可能小于 0
|
||||||
|
|
||||||
|
// 逐位提取数字(反向存储)
|
||||||
|
int start = 0;
|
||||||
|
do {
|
||||||
|
str[start++] = num % 10 + '0';
|
||||||
|
num /= 10;
|
||||||
|
} while (num > 0);
|
||||||
|
str[start] = '\0';
|
||||||
|
|
||||||
|
// 反转数字部分
|
||||||
|
char buf[16];
|
||||||
|
strncpy(buf, str, 16);
|
||||||
|
for(int i = 0; i < strlen(buf); i++)
|
||||||
|
str[--start] = buf[i];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef POINT_STR
|
||||||
|
#undef PERROR
|
71
program/c_cpp/library/self/log/log.h
Normal file
71
program/c_cpp/library/self/log/log.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Copyright(c) 2025 Rangersly All rights reserved.
|
||||||
|
//
|
||||||
|
// function :
|
||||||
|
// Output log
|
||||||
|
//
|
||||||
|
// Author:
|
||||||
|
// Rangersly
|
||||||
|
//
|
||||||
|
// Versions:
|
||||||
|
// - 1.0 base function
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#define LOG_INFO 0
|
||||||
|
#define LOG_WARNING 1
|
||||||
|
#define LOG_ERROR 2
|
||||||
|
#define LOG_FATAL 3
|
||||||
|
|
||||||
|
#define LOG_HEAD_MAX_FORMAT 32
|
||||||
|
|
||||||
|
// 如果未定义 NDEBUG 宏,错误发生时将打印错误信息
|
||||||
|
|
||||||
|
extern void
|
||||||
|
log_setoutfile(const char *restrict filename);
|
||||||
|
// 设置输出文件
|
||||||
|
// 默认输出为 stdout
|
||||||
|
|
||||||
|
extern void
|
||||||
|
log_setlevel(int level);
|
||||||
|
// 设置最低输出日志等级,低于最低等级的日志将忽略
|
||||||
|
|
||||||
|
extern void
|
||||||
|
log_sethead(const char *restrict head);
|
||||||
|
// 设置日志头,最大不可超过15个字符
|
||||||
|
// 符号表
|
||||||
|
// %y year
|
||||||
|
// %m month
|
||||||
|
// %d day
|
||||||
|
// %h hour
|
||||||
|
// %M minute
|
||||||
|
// %s second
|
||||||
|
// %n number
|
||||||
|
// %c core time .3f
|
||||||
|
|
||||||
|
extern void
|
||||||
|
log_print(int level, const char *restrict message);
|
||||||
|
// 输出日志 ^---等级 ^---输出信息
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// EXAMPLE
|
||||||
|
/*
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
log_setoutfile("log.out");
|
||||||
|
log_setlevel(LOG_ERROR);
|
||||||
|
log_sethead("#%d-%h-%M-%s-%n-%c#");
|
||||||
|
|
||||||
|
log_print(LOG_INFO, " hello");
|
||||||
|
log_print(LOG_WARNING, " hello");
|
||||||
|
log_print(LOG_ERROR, " hello");
|
||||||
|
log_print(LOG_FATAL, " hello");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*/
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## **1. 文本样式控制**
|
## **文本样式控制**
|
||||||
| 转义码 | 效果 | 说明 |
|
| 转义码 | 效果 | 说明 |
|
||||||
|---------------|--------------------|--------------------------|
|
|---------------|--------------------|--------------------------|
|
||||||
| `\033[0m` | 重置所有样式 | 关闭所有颜色和特效 |
|
| `\033[0m` | 重置所有样式 | 关闭所有颜色和特效 |
|
||||||
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## **2. 前景色(文本颜色)**
|
## **前景色**
|
||||||
| 转义码 | 颜色 | 转义码(亮色) |
|
| 转义码 | 颜色 | 转义码(亮色) |
|
||||||
|---------------|-----------|----------------|
|
|---------------|-----------|----------------|
|
||||||
| `\033[30m` | 黑色 | `\033[90m` |
|
| `\033[30m` | 黑色 | `\033[90m` |
|
||||||
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## **3. 背景色**
|
## **背景色**
|
||||||
| 转义码 | 颜色 | 转义码(亮色) |
|
| 转义码 | 颜色 | 转义码(亮色) |
|
||||||
|---------------|-----------|----------------|
|
|---------------|-----------|----------------|
|
||||||
| `\033[40m` | 黑色 | `\033[100m` |
|
| `\033[40m` | 黑色 | `\033[100m` |
|
||||||
@ -48,23 +48,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## **4. 光标控制**
|
## **RGB 颜色**
|
||||||
| 转义码 | 作用 |
|
|
||||||
|-------------------------|--------------------------|
|
|
||||||
| `\033[<n>A` | 光标上移 `<n>` 行 |
|
|
||||||
| `\033[<n>B` | 光标下移 `<n>` 行 |
|
|
||||||
| `\033[<n>C` | 光标右移 `<n>` 列 |
|
|
||||||
| `\033[<n>D` | 光标左移 `<n>` 列 |
|
|
||||||
| `\033[<y>;<x>H` | 光标移动到第 `<y>` 行、第 `<x>` 列 |
|
|
||||||
| `\033[2J` | 清屏(整个屏幕) |
|
|
||||||
| `\033[K` | 清除从光标到行尾的内容 |
|
|
||||||
| `\033[2K` | 清除全行的内容 |
|
|
||||||
| `\033[s` | 保存光标位置 |
|
|
||||||
| `\033[u` | 恢复光标位置 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## **5. RGB 颜色(部分终端支持)**
|
|
||||||
如果终端支持 **24-bit 真彩色**,可以使用:
|
如果终端支持 **24-bit 真彩色**,可以使用:
|
||||||
```c
|
```c
|
||||||
printf("\033[38;2;<r>;<g>;<b>m"); // 设置前景色(RGB)
|
printf("\033[38;2;<r>;<g>;<b>m"); // 设置前景色(RGB)
|
||||||
@ -74,3 +58,70 @@ printf("\033[48;2;<r>;<g>;<b>m"); // 设置背景色(RGB)
|
|||||||
```c
|
```c
|
||||||
printf("\033[38;2;255;100;0m这是橙红色文字\033[0m\n");
|
printf("\033[38;2;255;100;0m这是橙红色文字\033[0m\n");
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **光标控制**
|
||||||
|
| 转义码 | 作用 |
|
||||||
|
|-------------------------|--------------------------|
|
||||||
|
| `\033[<n>A` | 光标上移 `<n>` 行 |
|
||||||
|
| `\033[<n>B` | 光标下移 `<n>` 行 |
|
||||||
|
| `\033[<n>C` | 光标右移 `<n>` 列 |
|
||||||
|
| `\033[<n>D` | 光标左移 `<n>` 列 |
|
||||||
|
| `\033[<y>;<x>H` | 光标移动到第 `<y>` 行、第 `<x>` 列 |
|
||||||
|
| `\033[J` | 清屏(光标以后) |
|
||||||
|
| `\033[1J` | 清屏(光标以前) |
|
||||||
|
| `\033[2J` | 清屏(整个屏幕) |
|
||||||
|
| `\033[K` | 清除从光标到行尾的内容 |
|
||||||
|
| `\033[1K` | 清除从光标到行首的内容 |
|
||||||
|
| `\033[2K` | 清除全行的内容 |
|
||||||
|
| `\033[s` | 保存光标位置 |
|
||||||
|
| `\033[u` | 恢复光标位置 |
|
||||||
|
|
||||||
|
## **example**
|
||||||
|
```
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if __STDC__ != 1
|
||||||
|
#error "NO ansi !"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
printf("-----TEXT STYLE-----\n");
|
||||||
|
printf("\033[0m\\033[0m\033[0m\n");
|
||||||
|
printf("\033[1m\\033[1m\033[0m\n");
|
||||||
|
printf("\033[2m\\033[2m\033[0m\n");
|
||||||
|
printf("\033[3m\\033[3m\033[0m\n");
|
||||||
|
printf("\033[4m\\033[4m\033[0m\n");
|
||||||
|
printf("\033[5m\\033[5m\033[0m\n");
|
||||||
|
printf("\033[6m\\033[6m\033[0m\n");
|
||||||
|
printf("\033[7m\\033[7m\033[0m\n");
|
||||||
|
printf("\033[8m\\033[8m\033[0m\n");
|
||||||
|
printf("\033[9m\\033[9m\033[0m\n");
|
||||||
|
|
||||||
|
|
||||||
|
printf("\n-----COLOR-----\n");
|
||||||
|
printf("\033[30m\\033[30m\033[0m - \033[90m\\033[90m\033[0m\n");
|
||||||
|
printf("\033[31m\\033[31m\033[0m - \033[91m\\033[91m\033[0m\n");
|
||||||
|
printf("\033[32m\\033[32m\033[0m - \033[92m\\033[92m\033[0m\n");
|
||||||
|
printf("\033[33m\\033[33m\033[0m - \033[93m\\033[93m\033[0m\n");
|
||||||
|
printf("\033[34m\\033[34m\033[0m - \033[94m\\033[94m\033[0m\n");
|
||||||
|
printf("\033[35m\\033[35m\033[0m - \033[95m\\033[95m\033[0m\n");
|
||||||
|
printf("\033[36m\\033[36m\033[0m - \033[96m\\033[96m\033[0m\n");
|
||||||
|
printf("\033[37m\\033[37m\033[0m - \033[97m\\033[97m\033[0m\n");
|
||||||
|
printf("\033[38;2;112;223;234m\\033[38;2;112;223;234m\033[0m\n");
|
||||||
|
|
||||||
|
printf("\033[40m\\033[40m\033[0m - \033[100m\\033[100m\033[0m\n");
|
||||||
|
printf("\033[41m\\033[41m\033[0m - \033[101m\\033[101m\033[0m\n");
|
||||||
|
printf("\033[42m\\033[42m\033[0m - \033[102m\\033[102m\033[0m\n");
|
||||||
|
printf("\033[43m\\033[43m\033[0m - \033[103m\\033[103m\033[0m\n");
|
||||||
|
printf("\033[44m\\033[44m\033[0m - \033[104m\\033[104m\033[0m\n");
|
||||||
|
printf("\033[45m\\033[45m\033[0m - \033[105m\\033[105m\033[0m\n");
|
||||||
|
printf("\033[46m\\033[46m\033[0m - \033[106m\\033[106m\033[0m\n");
|
||||||
|
printf("\033[47m\\033[47m\033[0m - \033[107m\\033[107m\033[0m\n");
|
||||||
|
printf("\033[48;2;112;223;234m\\033[48;2;112;223;234m\033[0m\n");
|
||||||
|
|
||||||
|
printf("\033[0m\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
- [使用循环](#使用循环)
|
- [使用循环](#使用循环)
|
||||||
- [执行外部命令](#执行外部命令)
|
- [执行外部命令](#执行外部命令)
|
||||||
- [](#)
|
- [](#)
|
||||||
|
- [EXAMPLE](#example)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -471,3 +472,33 @@ FILE = ../file.c
|
|||||||
|
|
||||||
REAL_PATH = $(realpath $(FILE))
|
REAL_PATH = $(realpath $(FILE))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **example**
|
||||||
|
|
||||||
|
1. 通用模板
|
||||||
|
|
||||||
|
```makefile
|
||||||
|
# 定义编译器和编译选项
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = -c
|
||||||
|
LDFLAGS =
|
||||||
|
|
||||||
|
# 定义目标可执行文件名
|
||||||
|
TARGET = main
|
||||||
|
|
||||||
|
# 获取所有.c文件对应的.o文件
|
||||||
|
OBJS = $(patsubst %.c, %.o, $(wildcard *.c))
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJS)
|
||||||
|
$(CC) $(LDFLAGS) $^ -o $@
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o *.out $(TARGET)
|
||||||
|
```
|
||||||
|
Loading…
x
Reference in New Issue
Block a user