lab5: 支持子目录文件匹配
This commit is contained in:
parent
57c41ec11f
commit
cee4ec05ea
@ -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++;
|
||||
|
Loading…
x
Reference in New Issue
Block a user