mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-23 16:23:24 +00:00
🆕 printk.c, 在vsprintf中部分完成了解析字符串的工作
This commit is contained in:
7
.vscode/settings.json
vendored
Normal file
7
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"stdlib.h": "c",
|
||||
"stdbool.h": "c",
|
||||
"printk.h": "c"
|
||||
}
|
||||
}
|
171
kernel/printk.c
Normal file
171
kernel/printk.c
Normal file
@ -0,0 +1,171 @@
|
||||
//
|
||||
// Created by longjin on 2022/1/22.
|
||||
//
|
||||
#include "printk.h"
|
||||
|
||||
int skip_and_atoi(const char **s)
|
||||
{
|
||||
/**
|
||||
* @brief 获取连续的一段字符对应整数的值
|
||||
* @param:**s 指向 指向字符串的指针 的指针
|
||||
*/
|
||||
int ans = 0;
|
||||
while (is_digit(**s))
|
||||
{
|
||||
ans = ans * 10 + (**s) - '0';
|
||||
++(*s);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
int vsprintf(char *buf, const char *fmt, va_list args)
|
||||
{
|
||||
/**
|
||||
* 将字符串按照fmt和args中的内容进行格式化,然后保存到buf中
|
||||
* @param buf 结果缓冲区
|
||||
* @param fmt 格式化字符串
|
||||
* @param args 内容
|
||||
* @return 最终字符串的长度
|
||||
*/
|
||||
|
||||
char *str, *s;
|
||||
|
||||
str = buf;
|
||||
|
||||
int flags; // 用来存储格式信息的bitmap
|
||||
int field_width; //区域宽度
|
||||
int precision; //精度
|
||||
int qualifier; //数据显示的类型
|
||||
int len;
|
||||
|
||||
//开始解析字符串
|
||||
for (; *fmt; ++fmt)
|
||||
{
|
||||
//内容不涉及到格式化,直接输出
|
||||
if (*fmt != '%')
|
||||
{
|
||||
*str = *fmt;
|
||||
++str;
|
||||
}
|
||||
|
||||
//开始格式化字符串
|
||||
|
||||
//清空标志位和field宽度
|
||||
field_width = flags = 0;
|
||||
++fmt;
|
||||
|
||||
bool flag_tmp = true;
|
||||
bool flag_break = false;
|
||||
|
||||
while (flag_tmp)
|
||||
{
|
||||
switch (*fmt)
|
||||
{
|
||||
case '\0':
|
||||
//结束解析
|
||||
flag_break = true;
|
||||
flag_tmp = false;
|
||||
break;
|
||||
case '%':
|
||||
//输出 %
|
||||
*str = '%';
|
||||
++str;
|
||||
++fmt;
|
||||
flag_break = true;
|
||||
break;
|
||||
case '-':
|
||||
// 左对齐
|
||||
flags |= LEFT;
|
||||
++fmt;
|
||||
break;
|
||||
case '+':
|
||||
//在正数前面显示加号
|
||||
flags |= PLUS;
|
||||
++fmt;
|
||||
break;
|
||||
case ' ':
|
||||
flags |= SPACE;
|
||||
++fmt;
|
||||
break;
|
||||
case '#':
|
||||
//在八进制数前面显示 '0o',在十六进制数前面显示 '0x' 或 '0X'
|
||||
flags |= SPECIAL;
|
||||
++fmt;
|
||||
break;
|
||||
case '0':
|
||||
//显示的数字之前填充‘0’来取代空格
|
||||
flags |= PAD_ZERO;
|
||||
++fmt;
|
||||
break;
|
||||
default:
|
||||
flag_tmp = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag_break)
|
||||
break;
|
||||
|
||||
//获取区域宽度
|
||||
if (*fmt == '*')
|
||||
{
|
||||
field_width = va_arg(args, int);
|
||||
++fmt;
|
||||
}
|
||||
else if (is_digit(*fmt))
|
||||
field_width = skip_and_atoi(&fmt);
|
||||
|
||||
//获取小数精度
|
||||
if (*fmt == '.')
|
||||
{
|
||||
++fmt;
|
||||
if (*fmt == '*')
|
||||
{
|
||||
precision = va_arg(args, int);
|
||||
++fmt;
|
||||
}
|
||||
else if is_digit (*fmt)
|
||||
{
|
||||
precision = skip_and_atoi(&fmt);
|
||||
}
|
||||
}
|
||||
|
||||
//获取要显示的数据的类型
|
||||
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'Z')
|
||||
{
|
||||
qualifier = *fmt;
|
||||
++fmt;
|
||||
}
|
||||
|
||||
//转化成字符串
|
||||
|
||||
switch (*fmt)
|
||||
{
|
||||
// 显示一个字符
|
||||
case 'c':
|
||||
//靠右对齐
|
||||
if (!(flags & LEFT))
|
||||
{
|
||||
while (--field_width)
|
||||
{
|
||||
*str = ' ';
|
||||
++str;
|
||||
}
|
||||
}
|
||||
else //靠左对齐
|
||||
{
|
||||
*str = (char)va_arg(args, int);
|
||||
++str;
|
||||
--field_width;
|
||||
}
|
||||
while (--field_width)
|
||||
{
|
||||
*str = ' ';
|
||||
++str;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
34
kernel/printk.h
Normal file
34
kernel/printk.h
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// Created by longjin on 2022/1/21.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#define PAD_ZERO 1 // 0填充
|
||||
#define LEFT 2 // 靠左对齐
|
||||
#define RIGHT 4 //靠右对齐
|
||||
#define PLUS 8 // 在正数前面显示加号
|
||||
#define SPACE 16
|
||||
#define SPECIAL 32 //在八进制数前面显示 '0o',在十六进制数前面显示 '0x' 或 '0X'
|
||||
|
||||
|
||||
#define is_digit(c) ((c) >= '0' && (c) <= '9') // 用来判断是否是数字的宏
|
||||
|
||||
#include "font.h"
|
||||
#include "glib.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
struct screen_info
|
||||
{
|
||||
int width, height; //屏幕大小
|
||||
|
||||
int x, y; //光标位置
|
||||
|
||||
int char_size_x, char_size_y;
|
||||
|
||||
unsigned int *FB_address; //帧缓冲区首地址
|
||||
unsigned long FB_length; // 帧缓冲区长度
|
||||
} pos;
|
||||
|
||||
extern unsigned char font_ascii[256][16]; //导出ascii字体的bitmap(8*16大小)
|
||||
|
||||
char buf[4096]; //vsprintf()的缓冲区
|
Reference in New Issue
Block a user