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)];
|
static char file_complement_buf[MAX_FILE_COMPLEMENT_WORD * (MAX_FILENAME_LEN + 1)];
|
||||||
|
|
||||||
void path_to_absolute(char *path);
|
void path_to_absolute(char *path);
|
||||||
|
void path_append(char *path, char *sub);
|
||||||
int fs_scan(char *path);
|
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) {
|
static int make_file_complement_word(char ***ret_words, char *path_prefix, u8 type_mask) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
static char *words[MAX_FILE_COMPLEMENT_WORD];
|
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];
|
char pathbuf[BUFLEN];
|
||||||
|
|
||||||
// 当前目录
|
// 当前目录
|
||||||
// TODO: 支持更深路径的文件补全,如输入 tar 生成 tar/init.bin 等等
|
if (path_prefix == NULL) {
|
||||||
pathbuf[0] = '\0';
|
pathbuf[0] = '\0';
|
||||||
|
} else {
|
||||||
|
strcpy(pathbuf, path_prefix);
|
||||||
|
}
|
||||||
path_to_absolute(pathbuf);
|
path_to_absolute(pathbuf);
|
||||||
// 列出目录文件
|
// 列出目录文件
|
||||||
int ret = fs_scan(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) {
|
if ((dirat->d_type & type_mask) != 0) {
|
||||||
// 类型符合,加入结果
|
// 类型符合,加入结果
|
||||||
words[n++] = buf;
|
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;
|
buf += MAX_FILENAME_LEN + 1;
|
||||||
if (n >= MAX_FILE_COMPLEMENT_WORD) {
|
if (n >= MAX_FILE_COMPLEMENT_WORD) {
|
||||||
break;
|
break;
|
||||||
@ -114,9 +130,15 @@ static char *match_builtin_command_param(char *complement, int complement_time,
|
|||||||
// 跳过空格
|
// 跳过空格
|
||||||
while (complement[start_pos] == ' ')
|
while (complement[start_pos] == ' ')
|
||||||
start_pos++;
|
start_pos++;
|
||||||
// 匹配文件
|
// 匹配子目录文件
|
||||||
n_words = make_file_complement_word(&words, complement + start_pos, type_mask);
|
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);
|
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) {
|
if (matched) {
|
||||||
// 如果匹配到,就进行拼接
|
// 如果匹配到,就进行拼接
|
||||||
memcpy(buf, complement, start_pos);
|
memcpy(buf, complement, start_pos);
|
||||||
@ -134,10 +156,16 @@ static int do_complement(char *buf, char *complement, int complement_time)
|
|||||||
char **words;
|
char **words;
|
||||||
int n_words;
|
int n_words;
|
||||||
|
|
||||||
// 匹配文件
|
// 匹配子目录内文件,如 tar 匹配 tar/file1
|
||||||
n_words = make_file_complement_word(&words, complement, FTYPE_FILE);
|
n_words = make_file_complement_word(&words, complement, FTYPE_FILE);
|
||||||
matched = match_complement_words(words, n_words, complement, complement_time, &match_count);
|
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 内建指令
|
// 匹配 Shell 内建指令
|
||||||
if (!matched) {
|
if (!matched) {
|
||||||
words = builtin_complement_word;
|
words = builtin_complement_word;
|
||||||
@ -264,13 +292,15 @@ void path_to_absolute(char *path) {
|
|||||||
*/
|
*/
|
||||||
void path_append(char *path, char *sub) {
|
void path_append(char *path, char *sub) {
|
||||||
size_t path_len = strlen(path);
|
size_t path_len = strlen(path);
|
||||||
// path 末尾应该有 '/'
|
// 如果 path 不为空,则末尾应该有 '/'
|
||||||
|
if (path_len > 0) {
|
||||||
if (path[path_len - 1] == '/') {
|
if (path[path_len - 1] == '/') {
|
||||||
path += path_len;
|
path += path_len;
|
||||||
} else {
|
} else {
|
||||||
path[path_len] = '/';
|
path[path_len] = '/';
|
||||||
path += path_len + 1;
|
path += path_len + 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// sub 之前没有 '/'
|
// sub 之前没有 '/'
|
||||||
while (*sub == '/') sub++;
|
while (*sub == '/') sub++;
|
||||||
// 连接路径
|
// 连接路径
|
||||||
|
Loading…
x
Reference in New Issue
Block a user