lab5: 支持参数补全
This commit is contained in:
parent
591104e842
commit
57c41ec11f
@ -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,13 +56,15 @@ static int make_file_complement_word(char ***ret_words) {
|
||||
|
||||
for (int i = 0; i < ret; i++) {
|
||||
dirat = (struct dirent *) print_ptr;
|
||||
// 加入结果
|
||||
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);
|
||||
}
|
||||
|
||||
// 匹配结果
|
||||
|
Loading…
x
Reference in New Issue
Block a user