/// parses the command string void parse(teasafe::TeaSafe &theBfs, std::string const &commandStr, std::string &workingDir) { std::vector<std::string> comTokens; boost::algorithm::split_regex(comTokens, commandStr, boost::regex("\\s+")); if (comTokens[0] == "ls") { if (comTokens.size() > 1) { com_ls(theBfs, formattedPath(workingDir, comTokens[1])); } com_ls(theBfs, workingDir); } else if (comTokens[0] == "pwd") { std::cout<<workingDir<<std::endl; } else if (comTokens[0] == "rm") { if (comTokens.size() < 2) { std::cout<<"Error: please specify /path"<<std::endl; } else { com_rm(theBfs, formattedPath(workingDir, comTokens[1])); } } else if (comTokens[0] == "mkdir") { if (comTokens.size() < 2) { std::cout<<"Error: please specify /path"<<std::endl; } else { com_mkdir(theBfs, formattedPath(workingDir, comTokens[1])); } } else if (comTokens[0] == "add") { if (comTokens.size() < 2) { std::cout<<"Error: please specify file:///path"<<std::endl; } else { com_add(theBfs, workingDir, comTokens[1]); } } else if (comTokens[0] == "push") { if (comTokens.size() < 2) { std::cout<<"Error: please specify /path"<<std::endl; } else { com_push(theBfs, workingDir, comTokens[1]); } } else if (comTokens[0] == "pop") { com_pop(theBfs, workingDir); } else if (comTokens[0] == "cd") { if (comTokens.size() < 2) { std::cout<<"Error: please specify path"<<std::endl; } else { com_cd(theBfs, workingDir, formattedPath(workingDir, comTokens[1])); } } else if (comTokens[0] == "extract") { if (comTokens.size() < 3) { std::cout<<"Error: please specify /src/path and file:///dst/parent/path/"<<std::endl; } else { com_extract(theBfs, formattedPath(workingDir, comTokens[1]), comTokens[2]); } } else if (comTokens[0] == "help") { com_help(); } else if (comTokens[0] == "quit") { exit(0); } else if (comTokens[0] == "exit") { exit(0); } }
/// handles tab-key; attempts to provide rudimentary tab-completion void handleTabKey(teasafe::TeaSafe &theBfs, std::string const &workingPath, int &cursorPos, std::string &toReturn) { // get the token from the string that we're tring to tab-complete std::cout<<"\n"; std::vector<std::string> comTokens; boost::algorithm::split_regex(comTokens, toReturn, boost::regex("\\s+")); // if the user hasn't entered anything, simply list the available commands if(toReturn.empty()) { com_help(); std::cout<<"ts$> "<<toReturn; return; } // else process which bit to tab-complete std::string tabCompleted; size_t len; if(comTokens.size() > 1) { auto toBeCompleted(comTokens[comTokens.size()-1]); // make sure the working path is correctly formatted auto wd(workingPath); // if relative then append a slash to working path if(*toBeCompleted.begin() != '/') { // only append path seperator if wd isn't already root // which by definition, is '/' if(wd != "/") { wd.append("/"); } // append the bit that we want to tab-complete (void)wd.append(toBeCompleted); } else { // absolute // path begins with a '/' so must be absolute, thus // make workng path the actual token wd = toBeCompleted; } // run the tab-completion algorithm and get the tab-completed string back tabCompleted = tabCompleteTeaSafeEntry(theBfs, wd); len = (boost::filesystem::path(toBeCompleted).filename()).string().length(); } else { tabCompleted = tabCompleteCommand(comTokens[0]); len = comTokens[0].length(); } // how long is the original fname length prior to tab-completion? // Subtract from the original string this many characyers std::string copy(toReturn.begin(), toReturn.end() - len); copy.swap(toReturn); cursorPos -= len; // now append tab completed bit toReturn.append(tabCompleted); // updated cursor position based on returned string cursorPos += tabCompleted.length(); // after effect of pressing tab, need to print out prompt // and where we were with toReturn again std::cout<<"ts$> "<<toReturn; }
int main(int argc, char *argv[]) { setProgramStatus(EDITOR); if (argc == 1) { printf(1, "please input the command as [editor file_name]\n"); setProgramStatus(SHELL); exit(); } //存放文件内容 char *text[MAX_LINE_NUMBER] = {}; text[0] = malloc(MAX_LINE_LENGTH); memset(text[0], 0, MAX_LINE_LENGTH); //存储当前最大的行号,从0开始。即若line_number == x,则从text[0]到text[x]可用 int line_number = 0; //尝试打开文件 int fd = open(argv[1], O_RDONLY); //如果文件存在,则打开并读取里面的内容 if (fd != -1) { char buf[BUF_SIZE] = {}; int len = 0; while ((len = read(fd, buf, BUF_SIZE)) > 0) { int i = 0; int next = 0; int is_full = 0; while (i < len) { //拷贝"\n"之前的内容 for (i = next; i < len && buf[i] != '\n'; i++) ; strcat_n(text[line_number], buf+next, i-next); //必要时新建一行 if (i < len && buf[i] == '\n') { if (line_number >= MAX_LINE_NUMBER - 1) is_full = 1; else { line_number++; text[line_number] = malloc(MAX_LINE_LENGTH); memset(text[line_number], 0, MAX_LINE_LENGTH); } } if (is_full == 1 || i >= len - 1) break; else next = i + 1; } if (is_full == 1) break; } close(fd); } //输出文件内容 show_text(text); //输出帮助 com_help(text); //处理命令 char input[MAX_LINE_LENGTH] = {}; while (1) { printf(1, "\nplease input command:\n"); memset(input, 0, MAX_LINE_LENGTH); gets(input, MAX_LINE_LENGTH); int len = strlen(input); input[len-1] = '\0'; len --; //寻找命令中第一个空格 int pos = MAX_LINE_LENGTH - 1; int j = 0; for (; j < 8; j++) { if (input[j] == ' ') { pos = j + 1; break; } } //ins if (input[0] == 'i' && input[1] == 'n' && input[2] == 's') { if (input[3] == '-') com_ins(text, atoi(&input[4]), &input[pos]); else com_ins(text, line_number+1, &input[pos]); //插入操作需要更新行号 line_number = get_line_number(text); } //mod else if (input[0] == 'm' && input[1] == 'o' && input[2] == 'd') { if (input[3] == '-') com_mod(text, atoi(&input[4]), &input[pos]); else com_mod(text, line_number + 1, &input[pos]); } //del else if (input[0] == 'd' && input[1] == 'e' && input[2] == 'l') { if (input[3] == '-') com_del(text, atoi(&input[4])); else com_del(text, line_number + 1); //删除操作需要更新行号 line_number = get_line_number(text); } else if (strcmp(input, "show") == 0) { auto_show = 1; printf(1, "enable show current contents after text changed.\n"); } else if (strcmp(input, "hide") == 0) { auto_show = 0; printf(1, "disable show current contents after text changed.\n"); } else if (strcmp(input, "help") == 0) com_help(text); else if (strcmp(input, "save") == 0 || strcmp(input, "CTRL+S\n") == 0) com_save(text, argv[1]); else if (strcmp(input, "exit") == 0) com_exit(text, argv[1]); else { printf(1, "invalid command.\n"); com_help(text); } } setProgramStatus(SHELL); exit(); }