From d5ef9977cc0fab6d7dcdf30e2ab07b6d32809b89 Mon Sep 17 00:00:00 2001 From: xiaoyi1212 Date: Thu, 11 Apr 2024 23:32:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BA=86printf=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- boot/io.asm | 12 +- build.py | 6 +- include/common.h | 1 + include/graphics.h | 4 +- include/printf.h | 8 ++ sysapp/shell.c | 4 +- {kernel => util}/common.c | 206 ++-------------------------- util/printf.c | 281 ++++++++++++++++++++++++++++++++++++++ {data => util}/queue.c | 0 9 files changed, 316 insertions(+), 206 deletions(-) create mode 100644 include/printf.h rename {kernel => util}/common.c (56%) create mode 100644 util/printf.c rename {data => util}/queue.c (100%) diff --git a/boot/io.asm b/boot/io.asm index f3e9a0b..e383dfb 100644 --- a/boot/io.asm +++ b/boot/io.asm @@ -100,21 +100,21 @@ io_in32: ; int io_in32(int port); IN EAX,DX RET -io_out8: ; void io_out8(int port, int data); +io_out8: ; void io_out8(int port, int util); MOV EDX,[ESP+4] ; port - MOV AL,[ESP+8] ; data + MOV AL,[ESP+8] ; util OUT DX,AL RET -io_out16: ; void io_out16(int port, int data); +io_out16: ; void io_out16(int port, int util); MOV EDX,[ESP+4] ; port - MOV EAX,[ESP+8] ; data + MOV EAX,[ESP+8] ; util OUT DX,AX RET -io_out32: ; void io_out32(int port, int data); +io_out32: ; void io_out32(int port, int util); MOV EDX,[ESP+4] ; port - MOV EAX,[ESP+8] ; data + MOV EAX,[ESP+8] ; util OUT DX,EAX RET diff --git a/build.py b/build.py index a5537c2..6bdc6c9 100644 --- a/build.py +++ b/build.py @@ -53,9 +53,9 @@ def build_kernel(): # 构建内核本体 def build_data(): # 构建数据结构实现 - print("Building data source code...") - for file in os.listdir(cd + '\\data'): - cmd = cd + gcc + " " + "data\\" + file + " -o " + "target\\" + file.split(".")[0] + ".o" + print("Building util source code...") + for file in os.listdir(cd + '\\util'): + cmd = cd + gcc + " " + "util\\" + file + " -o " + "target\\" + file.split(".")[0] + ".o" e = os.system(cmd) if e != 0: return -1 diff --git a/include/common.h b/include/common.h index 3fa19a8..97efb3f 100644 --- a/include/common.h +++ b/include/common.h @@ -13,6 +13,7 @@ size_t strlen(const char* str); int strcmp(const char *s1, const char *s2); char *strcpy(char *dest, const char *src); char* strcat(char *dest, const char*src); +size_t strnlen(const char *s, size_t maxlen); void trim(char *s); int isspace(int c); int isdigit(int c); diff --git a/include/graphics.h b/include/graphics.h index 6e47f46..e252103 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -1,9 +1,7 @@ #ifndef CPOS_VGA_H #define CPOS_VGA_H -#include -#include -#include +#include "printf.h" /* * \032 DARK GRAY diff --git a/include/printf.h b/include/printf.h new file mode 100644 index 0000000..5a9c4d7 --- /dev/null +++ b/include/printf.h @@ -0,0 +1,8 @@ +#ifndef CRASHPOWEROS_PRINTF_H +#define CRASHPOWEROS_PRINTF_H + +#include +#include +#include + +#endif //CRASHPOWEROS_PRINTF_H diff --git a/sysapp/shell.c b/sysapp/shell.c index 695c1e9..f5c5ad1 100644 --- a/sysapp/shell.c +++ b/sysapp/shell.c @@ -96,7 +96,7 @@ void cmd_ls() { void cmd_cat(int argc, char **argv) { if (argc <= 2) { - printf("\033[Shell-CAT]: If there are too few parameters, please specify the filename and data.\036\n"); + printf("\033[Shell-CAT]: If there are too few parameters, please specify the filename and util.\036\n"); return; } struct File *file = open_file(argv[1]); @@ -216,7 +216,7 @@ void setup_shell(){ vga_writestring("version \032Print os version.\036\n"); vga_writestring("echo \032Print message.\036\n"); vga_writestring("ls \032List all files.\036\n"); - vga_writestring("cat \032Edit a file.\036\n"); + vga_writestring("cat \032Edit a file.\036\n"); vga_writestring("read \032Read a file.\036\n"); vga_writestring("mkdir \032Make a directory.\036\n"); vga_writestring("del rm \032Delete a file.\036\n"); diff --git a/kernel/common.c b/util/common.c similarity index 56% rename from kernel/common.c rename to util/common.c index fc1fb0c..a358442 100644 --- a/kernel/common.c +++ b/util/common.c @@ -5,13 +5,14 @@ static char num_str_buf[BUF_SIZE]; -int sprintf(char *buf, const char *fmt, ...) { - va_list args; - int retval; - va_start(args, fmt); - retval = vsprintf(buf, fmt, args); - va_end(args); - return retval; +size_t strnlen(const char *s, size_t maxlen) { + const char *es = s; + while (*es && maxlen) { + es++; + maxlen--; + } + + return (es - s); } size_t strlen(const char *str) { @@ -383,196 +384,17 @@ char *insert_str(char *buf, const char *str) { return p; } -int vsprintf(char *buf, const char *fmt, va_list args) { - char *str = buf; - int flag = 0; - int int_type = INT_TYPE_INT; - int tot_width = 0; - int sub_width = 0; - char buf2[64] = {0}; - char *s = NULL; - char ch = 0; - int8_t num_8 = 0; - uint8_t num_u8 = 0; - int16_t num_16 = 0; - uint16_t num_u16 = 0; - int32_t num_32 = 0; - uint32_t num_u32 = 0; - int64_t num_64 = 0; - uint64_t num_u64 = 0; - - for (const char *p = fmt; *p; p++) { - if (*p != '%') { - *str++ = *p; - continue; - } - - flag = 0; - tot_width = 0; - sub_width = 0; - int_type = INT_TYPE_INT; - - p++; - - while (*p == FLAG_ALTNT_FORM_CH || *p == FLAG_ZERO_PAD_CH || - *p == FLAG_LEFT_ADJUST_CH || *p == FLAG_SPACE_BEFORE_POS_NUM_CH || - *p == FLAG_SIGN_CH) { - if (*p == FLAG_ALTNT_FORM_CH) { - flag |= FLAG_ALTNT_FORM; - } else if (*p == FLAG_ZERO_PAD_CH) { - flag |= FLAG_ZERO_PAD; - } else if (*p == FLAG_LEFT_ADJUST_CH) { - flag |= FLAG_LEFT_ADJUST; - flag &= ~FLAG_ZERO_PAD; - } else if (*p == FLAG_SPACE_BEFORE_POS_NUM_CH) { - flag |= FLAG_SPACE_BEFORE_POS_NUM; - } else if (*p == FLAG_SIGN_CH) { - flag |= FLAG_SIGN; - } else { - } - - p++; - } - - if (*p == '*') { - tot_width = va_arg(args, - int); - if (tot_width < 0) - tot_width = 0; - p++; - } else { - while (isdigit(*p)) { - tot_width = tot_width * 10 + *p - '0'; - p++; - } - } - if (*p == '.') { - if (*p == '*') { - sub_width = va_arg(args, - int); - if (sub_width < 0) - sub_width = 0; - p++; - } else { - while (isdigit(*p)) { - sub_width = sub_width * 10 + *p - '0'; - p++; - } - } - } - - LOOP_switch: - switch (*p) { - case 'h': - p++; - if (int_type >= INT_TYPE_MIN) { - int_type >>= 1; - goto LOOP_switch; - } else { - *str++ = '%'; - break; - } - case 'l': - p++; - if (int_type <= INT_TYPE_MAX) { - int_type <<= 1; - goto LOOP_switch; - } else { - *str++ = '%'; - break; - } - case 's': - s = va_arg(args, - char *); - str = insert_str(str, s); - break; - case 'c': - ch = (char) (va_arg(args, - int) & - 0xFF); - *str++ = ch; - break; - case 'd': - switch (int_type) { - case INT_TYPE_CHAR: - num_8 = (int8_t) va_arg(args, int32_t); - str = insert_str(str, int32_to_str_dec(num_8, flag, tot_width)); - break; - case INT_TYPE_SHORT: - num_16 = (int16_t) va_arg(args, int32_t); - str = insert_str(str, int32_to_str_dec(num_16, flag, tot_width)); - break; - case INT_TYPE_INT: - num_32 = va_arg(args, int32_t); - str = insert_str(str, int32_to_str_dec(num_32, flag, tot_width)); - break; - case INT_TYPE_LONG: - num_64 = va_arg(args, int64_t); - str = insert_str(str, int64_to_str_dec(num_64, flag, tot_width)); - break; - case INT_TYPE_LONG_LONG: - num_64 = va_arg(args, int64_t); - str = insert_str(str, int64_to_str_dec(num_64, flag, tot_width)); - break; - } - break; - case 'x': - flag |= FLAG_LOWER; - case 'X': - switch (int_type) { - case INT_TYPE_CHAR: - num_u8 = (uint8_t) - va_arg(args, uint32_t); - str = insert_str(str, uint32_to_str_hex(num_u8, flag, tot_width)); - break; - case INT_TYPE_SHORT: - num_u16 = (uint16_t) - va_arg(args, uint32_t); - str = insert_str(str, uint32_to_str_hex(num_u16, flag, tot_width)); - break; - case INT_TYPE_INT: - num_u32 = va_arg(args, uint32_t); - str = insert_str(str, uint32_to_str_hex(num_u32, flag, tot_width)); - break; - case INT_TYPE_LONG: - num_u64 = va_arg(args, uint64_t); - str = insert_str(str, uint64_to_str_hex(num_u64, flag, tot_width)); - break; - case INT_TYPE_LONG_LONG: - num_u64 = va_arg(args, uint64_t); - str = insert_str(str, uint64_to_str_hex(num_u64, flag, tot_width)); - break; - } - break; - case 'o': - num_u32 = va_arg(args, uint32_t); - str = insert_str(str, uint32_to_str_oct(num_u32, flag, tot_width)); - break; - case '%': - *str++ = '%'; - break; - default: - *str++ = '%'; - *str++ = *p; - break; - } - } - *str = '\0'; - - return str - buf; -} - -void assert(int b,char* message){ - if(!b){ - printf("[KERNEL-PANIC]: %s",message); +void assert(int b, char *message) { + if (!b) { + printf("[KERNEL-PANIC]: %s", message); while (1) io_hlt(); } } -void trim(char *s){ +void trim(char *s) { char *p = s; int len = strlen(p); while (isspace(p[len - 1])) p[--len] = 0; - while (*p && isspace(*p)) ++p,--len; - memmove(s,p,len+1); + while (*p && isspace(*p)) ++p, --len; + memmove(s, p, len + 1); } diff --git a/util/printf.c b/util/printf.c new file mode 100644 index 0000000..d3b3ac8 --- /dev/null +++ b/util/printf.c @@ -0,0 +1,281 @@ +#include "../include/printf.h" +#include "../include/common.h" + +static int skip_atoi(const char **s) { + int i = 0; + + while (isdigit(**s)) + i = i * 10 + *((*s)++) - '0'; + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SMALL 32 /* Must be 32 == 0x20 */ +#define SPECIAL 64 /* 0x */ + +#define __do_div(n, base) ({ \ +int __res; \ +__res = ((unsigned long) n) % (unsigned) base; \ +n = ((unsigned long) n) / (unsigned) base; \ +__res; }) + +static char *number(char *str, long num, int base, int size, int precision, + int type) { + static const char digits[16] = "0123456789ABCDEF"; + + char tmp[66]; + char c, sign, locase; + int i; + + locase = (type & SMALL); + if (type & LEFT) + type &= ~ZEROPAD; + if (base < 2 || base > 16) + return NULL; + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) { + if (num < 0) { + sign = '-'; + num = -num; + size--; + } else if (type & PLUS) { + sign = '+'; + size--; + } else if (type & SPACE) { + sign = ' '; + size--; + } + } + if (type & SPECIAL) { + if (base == 16) + size -= 2; + else if (base == 8) + size--; + } + i = 0; + if (num == 0) + tmp[i++] = '0'; + else + while (num != 0) + tmp[i++] = (digits[__do_div(num, base)] | locase); + if (i > precision) + precision = i; + size -= precision; + if (!(type & (ZEROPAD + LEFT))) + while (size-- > 0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type & SPECIAL) { + if (base == 8) + *str++ = '0'; + else if (base == 16) { + *str++ = '0'; + *str++ = ('X' | locase); + } + } + if (!(type & LEFT)) + while (size-- > 0) + *str++ = c; + while (i < precision--) + *str++ = '0'; + while (i-- > 0) + *str++ = tmp[i]; + while (size-- > 0) + *str++ = ' '; + return str; +} + +int vsprintf(char *buf, const char *fmt, va_list args) { + int len; + unsigned long num; + int i, base; + char *str; + const char *s; + + int flags; /* flags to number() */ + + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier; /* 'h', 'l', or 'L' for integer fields */ + + for (str = buf; *fmt; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': + flags |= LEFT; + goto repeat; + case '+': + flags |= PLUS; + goto repeat; + case ' ': + flags |= SPACE; + goto repeat; + case '#': + flags |= SPECIAL; + goto repeat; + case '0': + flags |= ZEROPAD; + goto repeat; + } + + /* get field width */ + field_width = -1; + if (isdigit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + field_width = va_arg(args, + int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (isdigit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + precision = va_arg(args, + int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { + qualifier = *fmt; + ++fmt; + } + + /* default base */ + base = 10; + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, + int); + while (--field_width > 0) + *str++ = ' '; + continue; + + case 's': + s = va_arg(args, + char *); + len = strnlen(s, precision); + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + continue; + + case 'p': + if (field_width == -1) { + field_width = 2 * sizeof(void *); + flags |= ZEROPAD; + } + str = number(str, (unsigned long) va_arg(args, + void *), 16, + field_width, precision, flags); + continue; + + case 'n': + if (qualifier == 'l') { + long *ip = va_arg(args, + long *); + *ip = (str - buf); + } else { + int *ip = va_arg(args, + int *); + *ip = (str - buf); + } + continue; + + case '%': + *str++ = '%'; + continue; + + /* integer number formats - set up the flags and "break" */ + case 'o': + base = 8; + break; + + case 'x': + flags |= SMALL; + case 'X': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + break; + + default: + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + continue; + } + if (qualifier == 'l') + num = va_arg(args, + unsigned long); + else if (qualifier == 'h') { + num = (unsigned short) va_arg(args, + int); + if (flags & SIGN) + num = (short) num; + } else if (flags & SIGN) + num = va_arg(args, + int); + else + num = va_arg(args, + unsigned int); + str = number(str, num, base, field_width, precision, flags); + } + *str = '\0'; + return str - buf; +} + +int sprintf(char *buf, const char *fmt, ...) { + va_list args; + int i; + + va_start(args, fmt); + i = vsprintf(buf, fmt, args); + va_end(args); + return i; +} \ No newline at end of file diff --git a/data/queue.c b/util/queue.c similarity index 100% rename from data/queue.c rename to util/queue.c