From cee4ec05eaf21fee6fc18e53ae8a8ec2b0063bed Mon Sep 17 00:00:00 2001 From: KAAAsS Date: Thu, 21 Apr 2022 13:25:53 +0800 Subject: [PATCH] =?UTF-8?q?lab5:=20=E6=94=AF=E6=8C=81=E5=AD=90=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E6=96=87=E4=BB=B6=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab5/user/lab5/apps/init.c | 52 ++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/lab5/user/lab5/apps/init.c b/lab5/user/lab5/apps/init.c index 7e6999c..46fdec0 100644 --- a/lab5/user/lab5/apps/init.c +++ b/lab5/user/lab5/apps/init.c @@ -35,8 +35,16 @@ static int n_builtin_complement_word = sizeof(builtin_complement_word) / sizeof( static char file_complement_buf[MAX_FILE_COMPLEMENT_WORD * (MAX_FILENAME_LEN + 1)]; void path_to_absolute(char *path); +void path_append(char *path, char *sub); int fs_scan(char *path); +/** + * 生成文件补全词列表 + * @param ret_words 返回列表 + * @param path_prefix 文件的路径前缀,若不是文件夹返回空列表 + * @param type_mask 文件类型掩码 + * @return 列表长度 + */ 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]; @@ -44,8 +52,11 @@ static int make_file_complement_word(char ***ret_words, char *path_prefix, u8 ty char pathbuf[BUFLEN]; // 当前目录 - // TODO: 支持更深路径的文件补全,如输入 tar 生成 tar/init.bin 等等 - pathbuf[0] = '\0'; + if (path_prefix == NULL) { + pathbuf[0] = '\0'; + } else { + strcpy(pathbuf, path_prefix); + } path_to_absolute(pathbuf); // 列出目录文件 int ret = fs_scan(pathbuf); @@ -59,7 +70,12 @@ static int make_file_complement_word(char ***ret_words, char *path_prefix, u8 ty if ((dirat->d_type & type_mask) != 0) { // 类型符合,加入结果 words[n++] = buf; - strcpy(buf, dirat->d_name); + if (path_prefix == NULL) { + buf[0] = '\0'; + } else { + strcpy(buf, path_prefix); + } + path_append(buf, dirat->d_name); buf += MAX_FILENAME_LEN + 1; if (n >= MAX_FILE_COMPLEMENT_WORD) { break; @@ -114,9 +130,15 @@ static char *match_builtin_command_param(char *complement, int complement_time, // 跳过空格 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) { + n_words = make_file_complement_word(&words, NULL, type_mask); + matched = match_complement_words(words, n_words, complement + start_pos, complement_time, match_count); + } + // 匹配结果 if (matched) { // 如果匹配到,就进行拼接 memcpy(buf, complement, start_pos); @@ -134,10 +156,16 @@ static int do_complement(char *buf, char *complement, int complement_time) char **words; int n_words; - // 匹配文件 + // 匹配子目录内文件,如 tar 匹配 tar/file1 n_words = make_file_complement_word(&words, complement, FTYPE_FILE); matched = match_complement_words(words, n_words, complement, complement_time, &match_count); + // 匹配当前目录文件,如 f 匹配 file1 + if (!matched) { + n_words = make_file_complement_word(&words, NULL, FTYPE_FILE); + matched = match_complement_words(words, n_words, complement, complement_time, &match_count); + } + // 匹配 Shell 内建指令 if (!matched) { words = builtin_complement_word; @@ -264,12 +292,14 @@ void path_to_absolute(char *path) { */ void path_append(char *path, char *sub) { size_t path_len = strlen(path); - // path 末尾应该有 '/' - if (path[path_len - 1] == '/') { - path += path_len; - } else { - path[path_len] = '/'; - path += path_len + 1; + // 如果 path 不为空,则末尾应该有 '/' + if (path_len > 0) { + if (path[path_len - 1] == '/') { + path += path_len; + } else { + path[path_len] = '/'; + path += path_len + 1; + } } // sub 之前没有 '/' while (*sub == '/') sub++;