From 57c41ec11f42811f3ec874d59a58582dbeb6495c Mon Sep 17 00:00:00 2001 From: KAAAsS Date: Thu, 21 Apr 2022 13:08:46 +0800 Subject: [PATCH] =?UTF-8?q?lab5:=20=E6=94=AF=E6=8C=81=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E8=A1=A5=E5=85=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab5/user/lab5/apps/init.c | 74 +++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/lab5/user/lab5/apps/init.c b/lab5/user/lab5/apps/init.c index a3f1ae9..7e6999c 100644 --- a/lab5/user/lab5/apps/init.c +++ b/lab5/user/lab5/apps/init.c @@ -26,6 +26,9 @@ int fs_server_cap; #define MAX_FILE_COMPLEMENT_WORD 100 #define MAX_FILENAME_LEN 255 +#define FTYPE_FILE 0b01 +#define FTYPE_DIR 0b10 + static char *builtin_complement_word[] = {"cd", "ls", "ll", "cat", "echo", "clear"}; static int n_builtin_complement_word = sizeof(builtin_complement_word) / sizeof(char *); @@ -34,13 +37,14 @@ static char file_complement_buf[MAX_FILE_COMPLEMENT_WORD * (MAX_FILENAME_LEN + 1 void path_to_absolute(char *path); int fs_scan(char *path); -static int make_file_complement_word(char ***ret_words) { +static int make_file_complement_word(char ***ret_words, char *path_prefix, u8 type_mask) { int n = 0; static char *words[MAX_FILE_COMPLEMENT_WORD]; char *buf = file_complement_buf; char pathbuf[BUFLEN]; // 当前目录 + // TODO: 支持更深路径的文件补全,如输入 tar 生成 tar/init.bin 等等 pathbuf[0] = '\0'; path_to_absolute(pathbuf); // 列出目录文件 @@ -52,12 +56,14 @@ static int make_file_complement_word(char ***ret_words) { for (int i = 0; i < ret; i++) { dirat = (struct dirent *) print_ptr; - // 加入结果 - words[n++] = buf; - strcpy(buf, dirat->d_name); - buf += MAX_FILENAME_LEN + 1; - if (n >= MAX_FILE_COMPLEMENT_WORD) { - break; + if ((dirat->d_type & type_mask) != 0) { + // 类型符合,加入结果 + words[n++] = buf; + strcpy(buf, dirat->d_name); + buf += MAX_FILENAME_LEN + 1; + if (n >= MAX_FILE_COMPLEMENT_WORD) { + break; + } } print_ptr += dirat->d_reclen; } @@ -67,7 +73,11 @@ static int make_file_complement_word(char ***ret_words) { return n; } -static char *match_complement_words(char **words, size_t n, char *complement, size_t len, int complement_time, int *match_count) { +/** + * 在传入的匹配词中匹配补全 + */ +static char *match_complement_words(char **words, size_t n, char *complement, int complement_time, int *match_count) { + size_t len = strlen(complement); for (int i = 0; i < n; i++) { // 前缀匹配 if (strncmp(complement, words[i], len) != 0) @@ -80,24 +90,64 @@ static char *match_complement_words(char **words, size_t n, char *complement, si return NULL; } +/** + * 匹配内建指令的参数 + */ +static char *match_builtin_command_param(char *complement, int complement_time, int *match_count) { + u8 type_mask; + int start_pos; + char *matched = NULL; + char **words; + int n_words; + static char buf[BUFLEN]; + // 指令分类 + if (!strncmp(complement, "cd", 2) || !strncmp(complement, "ls", 2) || !strncmp(complement, "ll", 2)) { + type_mask = FTYPE_DIR; + start_pos = 2; + } else if (!strncmp(complement, "cat", 3)) { + type_mask = FTYPE_FILE; + start_pos = 3; + } else { + // 不支持的指令 + return NULL; + } + // 跳过空格 + while (complement[start_pos] == ' ') + start_pos++; + // 匹配文件 + n_words = make_file_complement_word(&words, complement + start_pos, type_mask); + matched = match_complement_words(words, n_words, complement + start_pos, complement_time, match_count); + if (matched) { + // 如果匹配到,就进行拼接 + memcpy(buf, complement, start_pos); + strcpy(buf + start_pos, matched); + return buf; + } + return NULL; +} + static int do_complement(char *buf, char *complement, int complement_time) { int r = -1; int match_count = 0; - size_t len = strlen(complement); char *matched = NULL; char **words; int n_words; // 匹配文件 - n_words = make_file_complement_word(&words); - matched = match_complement_words(words, n_words, complement, len, complement_time, &match_count); + n_words = make_file_complement_word(&words, complement, FTYPE_FILE); + matched = match_complement_words(words, n_words, complement, complement_time, &match_count); // 匹配 Shell 内建指令 if (!matched) { words = builtin_complement_word; n_words = n_builtin_complement_word; - matched = match_complement_words(words, n_words, complement, len, complement_time, &match_count); + matched = match_complement_words(words, n_words, complement, complement_time, &match_count); + } + + // 匹配 Shell 内建指令的参数 + if (!matched) { + matched = match_builtin_command_param(complement, complement_time, &match_count); } // 匹配结果