finish lab5 补全
This commit is contained in:
parent
1890a5d3fa
commit
03941b78ed
@ -12,6 +12,8 @@
|
||||
#define SERVER_READY_FLAG(vaddr) (*(int *)(vaddr))
|
||||
#define SERVER_EXIT_FLAG(vaddr) (*(int *)((u64)vaddr+ 4))
|
||||
|
||||
#define remove_char() {usys_putc('\b'); usys_putc(' '); usys_putc('\b');}
|
||||
|
||||
extern ipc_struct_t *tmpfs_ipc_struct;
|
||||
static ipc_struct_t ipc_struct;
|
||||
static int tmpfs_scan_pmo_cap;
|
||||
@ -21,14 +23,97 @@ static int tmpfs_read_pmo_cap;
|
||||
int fs_server_cap;
|
||||
|
||||
#define BUFLEN 4096
|
||||
#define MAX_FILE_COMPLEMENT_WORD 100
|
||||
#define MAX_FILENAME_LEN 255
|
||||
|
||||
static char *builtin_complement_word[] = {"cd", "ls", "ll", "cat", "echo", "clear"};
|
||||
static int n_builtin_complement_word = sizeof(builtin_complement_word) / sizeof(char *);
|
||||
|
||||
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) {
|
||||
int n = 0;
|
||||
static char *words[MAX_FILE_COMPLEMENT_WORD];
|
||||
char *buf = file_complement_buf;
|
||||
char pathbuf[BUFLEN];
|
||||
|
||||
// 当前目录
|
||||
pathbuf[0] = '\0';
|
||||
path_to_absolute(pathbuf);
|
||||
// 列出目录文件
|
||||
int ret = fs_scan(pathbuf);
|
||||
if (ret >= 0) {
|
||||
char *print_ptr;
|
||||
struct dirent *dirat;
|
||||
print_ptr = (char *) TMPFS_SCAN_BUF_VADDR;
|
||||
|
||||
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;
|
||||
}
|
||||
print_ptr += dirat->d_reclen;
|
||||
}
|
||||
}
|
||||
|
||||
*ret_words = &words[0];
|
||||
return n;
|
||||
}
|
||||
|
||||
static char *match_complement_words(char **words, size_t n, char *complement, size_t len, int complement_time, int *match_count) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
// 前缀匹配
|
||||
if (strncmp(complement, words[i], len) != 0)
|
||||
continue;
|
||||
// 补全计数检查
|
||||
if ((*match_count)++ >= complement_time) {
|
||||
return words[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int do_complement(char *buf, char *complement, int complement_time)
|
||||
{
|
||||
int r = -1;
|
||||
// TODO: your code here
|
||||
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);
|
||||
|
||||
// 匹配 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);
|
||||
}
|
||||
|
||||
// 匹配结果
|
||||
if (matched) {
|
||||
// 匹配到了
|
||||
strcpy(buf, matched);
|
||||
r = (int) strlen(buf);
|
||||
} else if (match_count > 0 && complement_time >= match_count) {
|
||||
// complement_time 大于一次循环
|
||||
r = do_complement(buf, complement, complement_time % match_count);
|
||||
} else {
|
||||
// 无匹配
|
||||
// printf("no match\n");
|
||||
}
|
||||
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
extern char getch();
|
||||
@ -54,6 +139,10 @@ char *readline(const char *prompt)
|
||||
c = getch();
|
||||
if (c < 0)
|
||||
return NULL;
|
||||
if (c != '\t') {
|
||||
// 重置补全计数
|
||||
complement_time = -1;
|
||||
}
|
||||
if (c == '\r') {
|
||||
// 回车
|
||||
usys_putc('\n');
|
||||
@ -62,9 +151,24 @@ char *readline(const char *prompt)
|
||||
// 退格
|
||||
if (i > 0) {
|
||||
i--;
|
||||
usys_putc('\b');
|
||||
usys_putc(' ');
|
||||
usys_putc('\b');
|
||||
remove_char();
|
||||
}
|
||||
continue;
|
||||
} else if (c == '\t') {
|
||||
// Tab
|
||||
if (complement_time < 0) {
|
||||
// 首次补全
|
||||
memcpy(complement, buf, i);
|
||||
complement[i] = '\0';
|
||||
}
|
||||
ret = do_complement(buf, complement, ++complement_time);
|
||||
if (ret > 0) {
|
||||
// 替换屏幕内容
|
||||
for (j = 0; j < i; j++)
|
||||
remove_char();
|
||||
i = ret;
|
||||
for (j = 0; j < i; j++)
|
||||
usys_putc(buf[j]);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
@ -140,12 +244,10 @@ int fs_scan(char *path)
|
||||
fr.count = count;
|
||||
|
||||
// 发送
|
||||
printf("Send ls: %s\n", path);
|
||||
ipc_msg_t *ipc_msg = ipc_create_msg(tmpfs_ipc_struct, sizeof(fr), 1);
|
||||
ipc_set_msg_data(ipc_msg, (void *)&fr, 0, sizeof(fr));
|
||||
ipc_set_msg_cap(ipc_msg, 0, tmpfs_scan_pmo_cap);
|
||||
ret = ipc_call(tmpfs_ipc_struct, ipc_msg);
|
||||
printf("Return ls: %d\n", ret);
|
||||
ipc_destroy_msg(ipc_msg);
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user