From 76913c736902ef86ba6a6cd58afeff80e617ef6c Mon Sep 17 00:00:00 2001 From: Ryosuke Date: Sat, 20 Aug 2022 20:57:59 +0900 Subject: [PATCH 01/31] =?UTF-8?q?=E9=AB=98=E6=A9=9F=E8=83=BD=E3=81=AA?= =?UTF-8?q?=E3=83=88=E3=83=BC=E3=82=AF=E3=83=8A=E3=82=A4=E3=82=B6=E3=82=92?= =?UTF-8?q?=E3=82=BF=E3=83=BC=E3=83=9F=E3=83=8A=E3=83=AB=E3=81=AB=E7=B5=84?= =?UTF-8?q?=E3=81=BF=E8=BE=BC=E3=81=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/Makefile | 2 +- kernel/terminal.cpp | 265 +++++++++++++++++++++---------------------- kernel/terminal.hpp | 4 +- kernel/tokenizer.cpp | 117 +++++++++++++++++++ kernel/tokenizer.hpp | 27 +++++ 5 files changed, 277 insertions(+), 138 deletions(-) create mode 100644 kernel/tokenizer.cpp create mode 100644 kernel/tokenizer.hpp diff --git a/kernel/Makefile b/kernel/Makefile index 14fd57af6..ab6bb154f 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,7 +1,7 @@ TARGET = kernel.elf OBJS = main.o graphics.o mouse.o font.o hankaku.o newlib_support.o console.o \ pci.o asmfunc.o libcxx_support.o logger.o interrupt.o segment.o paging.o memory_manager.o \ - window.o layer.o timer.o frame_buffer.o acpi.o keyboard.o task.o terminal.o \ + window.o layer.o timer.o frame_buffer.o acpi.o keyboard.o task.o terminal.o tokenizer.o \ fat.o syscall.o file.o \ usb/memory.o usb/device.o usb/xhci/ring.o usb/xhci/trb.o usb/xhci/xhci.o \ usb/xhci/port.o usb/xhci/device.o usb/xhci/devmgr.o usb/xhci/registers.o \ diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index 9fdd5d99d..e8b5a0479 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -17,12 +17,14 @@ #include "keyboard.hpp" #include "logger.hpp" #include "uefi.hpp" +#include "tokenizer.hpp" #include "usb/classdriver/cdc.hpp" #include "usb/xhci/xhci.hpp" + namespace { -WithError MakeArgVector(char* command, char* first_arg, +WithError MakeArgVector(std::vector args, char** argv, int argv_len, char* argbuf, int argbuf_len) { int argc = 0; int argbuf_index = 0; @@ -39,36 +41,14 @@ WithError MakeArgVector(char* command, char* first_arg, return MAKE_ERROR(Error::kSuccess); }; - if (auto err = push_to_argv(command)) { - return { argc, err }; - } - if (!first_arg) { + if (!args.size()) { return { argc, MAKE_ERROR(Error::kSuccess) }; } - char* p = first_arg; - while (true) { - while (isspace(p[0])) { - ++p; - } - if (p[0] == 0) { - break; - } - const char* arg = p; - - while (p[0] != 0 && !isspace(p[0])) { - ++p; - } - // here: p[0] == 0 || isspace(p[0]) - const bool is_end = p[0] == 0; - p[0] = 0; - if (auto err = push_to_argv(arg)) { + for (int i = 0; i < args.size(); i++) { + if (auto err = push_to_argv(args[i].c_str())) { return { argc, err }; } - if (is_end) { - break; - } - ++p; } return { argc, MAKE_ERROR(Error::kSuccess) }; @@ -335,21 +315,38 @@ Rectangle Terminal::InputKey( if (ascii == '\n') { linebuf_[linebuf_index_] = 0; - if (linebuf_index_ > 0) { - cmd_history_.pop_back(); - cmd_history_.push_front(linebuf_); - } - linebuf_index_ = 0; - cmd_history_index_ = -1; + std::vector tokens; + int redir_idx = -1, *p_redir = &redir_idx; + int pipe_idx = -1, *p_pipe = &pipe_idx; + struct TokenizerInnerState *t = nullptr; + t = tokenize(&linebuf_[0], tokens, p_redir, p_pipe, t); + if (t) { // input not end + cursor_.x = 0; + if (cursor_.y < kRows - 1) { + ++cursor_.y; + } else { + Scroll1(); + } + linebuf_[linebuf_index_] = ascii; + ++linebuf_index_; + Print("<"); + } else { // input end + if (linebuf_index_ > 0) { + cmd_history_.pop_back(); + cmd_history_.push_front(linebuf_); + } + linebuf_index_ = 0; + cmd_history_index_ = -1; - cursor_.x = 0; - if (cursor_.y < kRows - 1) { - ++cursor_.y; - } else { - Scroll1(); + cursor_.x = 0; + if (cursor_.y < kRows - 1) { + ++cursor_.y; + } else { + Scroll1(); + } + ExecuteLine(tokens, redir_idx, pipe_idx); + Print(">"); } - ExecuteLine(); - Print(">"); draw_area.pos = ToplevelWindow::kTopLeftMargin; draw_area.size = window_->InnerSize(); } else if (ascii == '\b') { @@ -394,37 +391,21 @@ void Terminal::Scroll1() { {4, 4 + 16*cursor_.y}, {8*kColumns, 16}, {0, 0, 0}); } -void Terminal::ExecuteLine() { - char* command = &linebuf_[0]; - char* first_arg = strchr(&linebuf_[0], ' '); - char* redir_char = strchr(&linebuf_[0], '>'); - char* pipe_char = strchr(&linebuf_[0], '|'); - char* command_end = &linebuf_[strlen(&linebuf_[0])]; - - auto trim_space = [&command](char* end_ptr) { - while (command < end_ptr && isspace(end_ptr[-1])) { - *--end_ptr = 0; - } - }; - trim_space(command_end); - - if (first_arg) { - *first_arg = 0; - do { - ++first_arg; - } while (isspace(*first_arg)); - } +void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pipe_idx) { + std::string str_command = args[0]; + const char* command = str_command.c_str(); auto original_stdout = files_[1]; int exit_code = 0; - if (redir_char) { - *redir_char = 0; - trim_space(redir_char); - char* redir_dest = &redir_char[1]; - while (isspace(*redir_dest)) { - ++redir_dest; + if (redir_idx != -1 && redir_idx != 0) { + if (args.size() < redir_idx + 2) { + PrintToFD(*files_[2], + "failed to create a redirect file"); + return; } + const char* redir_dest = args[redir_idx+1].c_str(); + args.erase(args.begin() + redir_idx, args.end()); auto [ file, post_slash ] = fat::FindFile(redir_dest); if (file == nullptr) { @@ -445,13 +426,11 @@ void Terminal::ExecuteLine() { std::shared_ptr pipe_fd; uint64_t subtask_id = 0; - if (pipe_char) { - *pipe_char = 0; - trim_space(pipe_char); + if (pipe_idx != -1 && pipe_idx != 0) { + args.erase(args.begin() + pipe_idx-1, args.end()); + + char* pipe_char = strchr(&linebuf_[0], '|'); char* subcommand = &pipe_char[1]; - while (isspace(*subcommand)) { - ++subcommand; - } auto& subtask = task_manager->NewTask(); pipe_fd = std::make_shared(subtask); @@ -468,13 +447,21 @@ void Terminal::ExecuteLine() { (*layer_task_map)[layer_id_] = subtask_id; } - if (strcmp(command, "echo") == 0) { - if (first_arg && first_arg[0] == '$') { - if (strcmp(&first_arg[1], "?") == 0) { + if (strcmp(command, ">") == 0) { + PrintToFD(*files_[2], "no command befoer > \n"); + exit_code = 1; + } else if (strcmp(command, "|") == 0) { + PrintToFD(*files_[2], "no command befoer | \n"); + exit_code = 1; + } else if (strcmp(command, "echo") == 0) { + if (args.size() > 1) { + if (args[1] == "$?") { PrintToFD(*files_[1], "%d", last_exit_code_); + } else { + for (int i = 1; i < args.size(); i++) { + PrintToFD(*files_[1], "%s ", args[i].c_str()); + } } - } else if (first_arg) { - PrintToFD(*files_[1], "%s", first_arg); } PrintToFD(*files_[1], "\n"); } else if (strcmp(command, "clear") == 0) { @@ -493,73 +480,80 @@ void Terminal::ExecuteLine() { dev.class_code.base, dev.class_code.sub, dev.class_code.interface); } } else if (strcmp(command, "ls") == 0) { - char* file_name = first_arg; bool verbose = false; - if (file_name && file_name[0] == '-') { - for (++file_name; *file_name && !isspace(*file_name); ++file_name) { - if (*file_name == 'l') verbose = true; - } - while (isspace(*file_name)) file_name++; - } - if (!file_name || file_name[0] == '\0') { + if (args.size() < 2) { ListAllEntries(*files_[1], fat::boot_volume_image->root_cluster, verbose); } else { - auto [ dir, post_slash ] = fat::FindFile(file_name); - if (dir == nullptr) { - PrintToFD(*files_[2], "No such file or directory: %s\n", file_name); - exit_code = 1; - } else if (dir->attr == fat::Attribute::kDirectory) { - ListAllEntries(*files_[1], dir->FirstCluster(), verbose); - } else { - char name[13]; - fat::FormatName(*dir, name); - if (post_slash) { - PrintToFD(*files_[2], "%s is not a directory\n", name); - exit_code = 1; - } else { - if (verbose) { - PrintFileAttr(*files_[1], *dir); + if (strcmp(args[1].c_str(), "-l") == 0) { + verbose = true; + args.erase(args.begin() + 1); + } + if (args.size() >= 2) { + for (int i = 1; i < args.size(); i++) { + const char* file_name = args[i].c_str(); + auto [ dir, post_slash ] = fat::FindFile(file_name); + if (dir == nullptr) { + PrintToFD(*files_[2], "No such file or directory: %s\n", file_name); + exit_code = 1; + } else if (dir->attr == fat::Attribute::kDirectory) { + ListAllEntries(*files_[1], dir->FirstCluster(), verbose); } else { - if (files_[1]->IsTerminal() && dir->attr == fat::Attribute::kDirectory) { - PrintToFD(*files_[1], "\033[94m%s\033[0m\n", name); + char name[13]; + fat::FormatName(*dir, name); + if (post_slash) { + PrintToFD(*files_[2], "%s is not a directory\n", name); + exit_code = 1; } else { - PrintToFD(*files_[1], "%s\n", name); + if (verbose) { + PrintFileAttr(*files_[1], *dir); + } else { + PrintToFD(*files_[1], "%s\n", name); + } } } } + } else { + ListAllEntries(*files_[1], fat::boot_volume_image->root_cluster, verbose); } } + } else if (strcmp(command, "cat") == 0) { - std::shared_ptr fd; - if (!first_arg || first_arg[0] == '\0') { - fd = files_[0]; + std::vector> fd_vec; + if (args.size() < 2) { + fd_vec.push_back(files_[0]); } else { - auto [ file_entry, post_slash ] = fat::FindFile(first_arg); - if (!file_entry) { - PrintToFD(*files_[2], "no such file: %s\n", first_arg); - exit_code = 1; - } else if (file_entry->attr != fat::Attribute::kDirectory && post_slash) { - char name[13]; - fat::FormatName(*file_entry, name); - PrintToFD(*files_[2], "%s is not a directory\n", name); - exit_code = 1; - } else { - fd = std::make_shared(*file_entry); + for (int i = 1; i < args.size(); i++) { + auto [ file_entry, post_slash ] = fat::FindFile(args[i].c_str()); + if (!file_entry) { + PrintToFD(*files_[2], "no such file: %s\n", args[i].c_str()); + exit_code = 1; + } else if (file_entry->attr != fat::Attribute::kDirectory && post_slash) { + char name[13]; + fat::FormatName(*file_entry, name); + PrintToFD(*files_[2], "%s is not a directory\n", name); + exit_code = 1; + } else { + fd_vec.push_back(std::make_shared(*file_entry)); + } } } - if (fd) { - char u8buf[1024]; - DrawCursor(false); - while (true) { - size_t read_size = ReadDelim(*fd, '\n', u8buf, sizeof(u8buf)); - if (read_size == 0) { - break; + for (int i = 0; i < fd_vec.size(); i++) { + auto fd = fd_vec[i]; + if (fd) { + char u8buf[1024]; + DrawCursor(false); + while (true) { + size_t read_size = ReadDelim(*fd, '\n', u8buf, sizeof(u8buf)); + if (read_size == 0) { + break; + } + files_[1]->Write(u8buf, read_size); } - files_[1]->Write(u8buf, read_size); + DrawCursor(true); } - DrawCursor(true); } } else if (strcmp(command, "noterm") == 0) { + char* first_arg = strchr(&linebuf_[0], ' '); auto term_desc = new TerminalDescriptor{ first_arg, true, false, files_ }; @@ -615,11 +609,12 @@ void Terminal::ExecuteLine() { exit_code = 1; return; } - size_t send_len; - if (first_arg && first_arg[0]) { - send_len = strlen(first_arg); - usb::cdc::driver->SendSerial(first_arg, send_len); + if (args.size() < 2) { + for (int i = 1; i < args.size(); i++) { + send_len = strlen(args[i].c_str()); + usb::cdc::driver->SendSerial(args[i].c_str(), send_len); + } } else { send_len = 1; usb::cdc::driver->SendSerial("a", 1); @@ -642,9 +637,9 @@ void Terminal::ExecuteLine() { 8 }; - if (first_arg && first_arg[0]) { + if (args.size() < 2) { char *endp; - line_coding.dte_rate = strtol(first_arg, &endp, 0); + line_coding.dte_rate = strtol(args[1].c_str(), &endp, 0); if (*endp != '\0') { PrintToFD(*files_[2], "Baud rate must be an integer"); exit_code = 1; @@ -671,7 +666,7 @@ void Terminal::ExecuteLine() { std::vector insn; - if (first_arg && strcmp(first_arg, "sample") == 0) { + if (args.size() < 2 && strcmp(args[1].c_str(), "sample") == 0) { const std::array kSample = { 0x00, 0x20, 0xC1, 0x00, @@ -717,7 +712,7 @@ void Terminal::ExecuteLine() { PrintToFD(*files_[2], "no such command: %s\n", command); exit_code = 1; } else { - auto [ ec, err ] = ExecuteFile(*file_entry, command, first_arg); + auto [ ec, err ] = ExecuteFile(*file_entry, command, args); if (err) { PrintToFD(*files_[2], "failed to exec file: %s\n", err.Name()); exit_code = -ec; @@ -744,7 +739,7 @@ void Terminal::ExecuteLine() { } WithError Terminal::ExecuteFile(fat::DirectoryEntry& file_entry, - char* command, char* first_arg) { + const char* command, std::vector& args) { __asm__("cli"); auto& task = task_manager->CurrentTask(); __asm__("sti"); @@ -762,7 +757,7 @@ WithError Terminal::ExecuteFile(fat::DirectoryEntry& file_entry, int argv_len = 32; // argv = 8x32 = 256 bytes auto argbuf = reinterpret_cast(args_frame_addr.value + sizeof(char*) * argv_len); int argbuf_len = 4096 - sizeof(char*) * argv_len; - auto argc = MakeArgVector(command, first_arg, argv, argv_len, argbuf, argbuf_len); + auto argc = MakeArgVector(args, argv, argv_len, argbuf, argbuf_len); if (argc.error) { return { 0, argc.error }; } diff --git a/kernel/terminal.hpp b/kernel/terminal.hpp index a00d4b56c..fe4570e23 100644 --- a/kernel/terminal.hpp +++ b/kernel/terminal.hpp @@ -68,9 +68,9 @@ class Terminal { std::array linebuf_{}; void Scroll1(); - void ExecuteLine(); + void ExecuteLine(std::vector& tokens, int redir, int pipes); WithError ExecuteFile(fat::DirectoryEntry& file_entry, - char* command, char* first_arg); + const char* command, std::vector& args); void Print(char32_t c); std::deque> cmd_history_{}; diff --git a/kernel/tokenizer.cpp b/kernel/tokenizer.cpp new file mode 100644 index 000000000..07da23bd9 --- /dev/null +++ b/kernel/tokenizer.cpp @@ -0,0 +1,117 @@ +#include "tokenizer.hpp" + +#include +#include + +TokenizerInnerState *tokenize(const char *c, std::vector& tokens, + int *redir_idx, int *pipe_idx, TokenizerInnerState *last_istate) { + State state = Init; + State last_state = Init; + std::string tmp_token; + if (last_istate) { + state = last_istate->state; + last_state = last_istate->last_state; + tmp_token = last_istate->tmp_token; + } + auto update_state = [&](State new_state) { + last_state = state; state = new_state; + }; + auto revert_state = [&](State new_state) { + state = last_state; last_state = new_state; + }; + while (true) { + switch (state) { + case BackSlash: + if (!*c) { revert_state(BackSlash); break; } + switch (last_state) { + case Init: + if (!isspace(*c)) { tmp_token = *c; } + state = InToken; last_state = BackSlash; + break; + case InToken: + if (*c != '\n') { tmp_token += *c; } + revert_state(BackSlash); + break; + case InDoubleQuoted: + case InSingleQuoted: + if (*c != '\n') { + tmp_token += '\\'; + tmp_token += *c; + } + revert_state(BackSlash); + break; + } + break; + case Init: + if (*c == '>' || *c == '|') { + tmp_token = *c; + tokens.push_back(tmp_token); + if (*c == '>' && *redir_idx == -1) { *redir_idx = tokens.size() -1; } + if (*c == '|' && *pipe_idx == -1) { *pipe_idx = tokens.size() -1; } + } else if (*c == '"') { + update_state(InDoubleQuoted); + tmp_token = c[1]; + c++; + } else if (*c == '\'') { + update_state(InSingleQuoted); + tmp_token = c[1]; + c++; + } else if (!isspace(*c) && *c) { + update_state(InToken); + tmp_token = *c; + } + break; + case InToken: + if (*c == '>' || *c == '|') { + update_state(Init); + tokens.push_back(tmp_token); + tmp_token = *c; + tokens.push_back(tmp_token); + if (*c == '>' && *redir_idx == -1) { *redir_idx = tokens.size() -1; } + if (*c == '|' && *pipe_idx == -1) { *pipe_idx = tokens.size() -1; } + } + if (isspace(*c) || *c == '\0') { + update_state(Init); + tokens.push_back(tmp_token); + tmp_token.clear(); + } else if (*c != '"' && *c != '\'') { + tmp_token += *c; + } + break; + case InDoubleQuoted: + if (*c == '"') { + update_state(Init); + tokens.push_back(tmp_token); + tmp_token.clear(); + } else if (*c) { + tmp_token += *c; + } + break; + case InSingleQuoted: + if (*c == '\'') { + update_state(Init); + tokens.push_back(tmp_token); + tmp_token.clear(); + } else if (*c) { + tmp_token += *c; + } + break; + } + if (*c == '\0') { break; } + c++; + if (*c == '\\') { + update_state(BackSlash); c++; + } + } + if (state != Init || (state == Init && last_state == BackSlash)) { + if (!last_istate) { + last_istate = new TokenizerInnerState ; + } + last_istate->state = state; + last_istate->last_state = last_state; + last_istate->tmp_token = tmp_token; + return last_istate; + } else { + return nullptr; + } +} \ No newline at end of file diff --git a/kernel/tokenizer.hpp b/kernel/tokenizer.hpp new file mode 100644 index 000000000..4ea005a5b --- /dev/null +++ b/kernel/tokenizer.hpp @@ -0,0 +1,27 @@ +/** + * @file tokenizer.hpp + * + * シェルのトークナイザを提供する。 + */ + +#pragma once + +#include +#include + +enum State { + Init, + InToken, + InDoubleQuoted, + InSingleQuoted, + BackSlash, +}; + +struct TokenizerInnerState { + State state; + State last_state; + std::string tmp_token; +}; + +TokenizerInnerState *tokenize(const char *c, std::vector& tokens, + int *redir_idx, int *pipe_idx, TokenizerInnerState *last_istate); \ No newline at end of file From 8a7e48d687c782d632487956f5a956dc11e7af83 Mon Sep 17 00:00:00 2001 From: Ryosuke Date: Sat, 20 Aug 2022 20:58:47 +0900 Subject: [PATCH 02/31] =?UTF-8?q?=E3=83=88=E3=83=BC=E3=82=AF=E3=83=8A?= =?UTF-8?q?=E3=82=A4=E3=82=B6=E3=81=AE=E3=83=86=E3=82=B9=E3=83=88=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/tests/.gitignore | 2 + kernel/tests/Makefile | 26 +++++++++ kernel/tests/main.cpp | 17 ++++++ kernel/tests/tokenizer_test.cpp | 98 +++++++++++++++++++++++++++++++++ kernel/tests/tokenizer_test.hpp | 7 +++ 5 files changed, 150 insertions(+) create mode 100644 kernel/tests/.gitignore create mode 100644 kernel/tests/Makefile create mode 100644 kernel/tests/main.cpp create mode 100644 kernel/tests/tokenizer_test.cpp create mode 100644 kernel/tests/tokenizer_test.hpp diff --git a/kernel/tests/.gitignore b/kernel/tests/.gitignore new file mode 100644 index 000000000..5e9c83484 --- /dev/null +++ b/kernel/tests/.gitignore @@ -0,0 +1,2 @@ +/tests +/*.o diff --git a/kernel/tests/Makefile b/kernel/tests/Makefile new file mode 100644 index 000000000..e3c5327e5 --- /dev/null +++ b/kernel/tests/Makefile @@ -0,0 +1,26 @@ +CFLAGS += -O2 -Wall -g +CXXFLAGS += -O2 -Wall -g + +TARGET = tests +OBJS = main.o tokenizer.o tokenizer_test.o + +.PHONY: all +all: $(TARGET) + +.PHONY: clean +clean: + rm -rf *.o $(TARGET) + +$(TARGET): $(OBJS) Makefile + clang++ $(LDFLAGS) -o $@ $(OBJS) -fuse-ld=lld + +tokenizer.o: ../tokenizer.cpp Makefile + clang++ $(CPPFLAGS) $(CFLAGS) -c $< -o $@ + +%.o: %.cpp Makefile + clang++ $(CPPFLAGS) $(CFLAGS) -c $< -o $@ + +.PHONY: test +test: $(TARGET) + ./$(TARGET) + diff --git a/kernel/tests/main.cpp b/kernel/tests/main.cpp new file mode 100644 index 000000000..ce7b795d2 --- /dev/null +++ b/kernel/tests/main.cpp @@ -0,0 +1,17 @@ + +#include "tokenizer_test.hpp" + +int main() { + int ret = 0; + + printf("test: tokenizer\n"); + ret = ret | test_tokenize(); + + if (ret) { + printf("\e[38;5;9mERR\e[0m\n"); + } else { + printf("\e[38;5;10mOK\e[0m\n"); + } + + return ret; +} diff --git a/kernel/tests/tokenizer_test.cpp b/kernel/tests/tokenizer_test.cpp new file mode 100644 index 000000000..032163d14 --- /dev/null +++ b/kernel/tests/tokenizer_test.cpp @@ -0,0 +1,98 @@ +#include "tokenizer_test.hpp" + +#include +#include +#include +#include +#include + +#include "../tokenizer.hpp" + +bool isTISsame(struct TokenizerInnerState *tis1, struct TokenizerInnerState *tis2) { + if (tis1 == nullptr ^ tis2 == nullptr) { return false; } + if (tis1 == nullptr && tis2 == nullptr) { return true; } + if (tis1->last_state != tis2->last_state) { return false; } + if (tis1->last_state != tis2->last_state) { return false; } + if (tis1->tmp_token != tis2->tmp_token) { return false; } + return true; +} + +void printTIS(struct TokenizerInnerState *tis) { + std::cout << " >>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl; + if (!tis) { std::cout << " nullptr" << std::endl; } + else { + std::cout << " stete: " << tis->last_state << std::endl; + std::cout << " last_state: " << tis->last_state << std::endl; + std::cout << " tmp_token: `" << tis->tmp_token << "`" << std::endl; + std::cout << " len(tmp_token): " << tis->tmp_token.length() << std::endl; + } + std::cout << " <<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl; +} + +int test_tokenize() { + int ret = 0; + struct TokenizerInnerState t0 = { InToken, BackSlash, "hoge"}; + struct TokenizerInnerState t5 = { InDoubleQuoted, Init, "piyo"}; + struct TokenizerInnerState t2 = { Init, BackSlash, ""}; + struct TokenizerInnerState t9 = { InDoubleQuoted, Init, "ed> hoge"}; + struct { + const int expected; + const char* result[32]; + int redir; + int pipe; + char linebuf[100]; + struct TokenizerInnerState *eis; // expected + struct TokenizerInnerState *iis; // input + } tbl[] = { + /* 00 */ {9, {"hoge", "|", "fuga", "|", "piyo", ">", "foo", ">", "bar"}, 5, 1, R"(hoge |fuga| piyo >foo> bar)", nullptr, nullptr}, + // パイプ, 空白の前後が空白、複数のリダイレクト + /* 01 */ {3, {"minied", "-p", "mini|ed>"}, -1, -1, R"(minied -p "mini|ed>" hoge\)", &t0, nullptr}, + // ダブルクォート中のリダイレクト, パイプ、\終端 + /* 02 */ {4, {"hoge", ">", "piyo", "|"}, -1, -1, R"(hoge ">" piyo '|')", nullptr, nullptr}, + // クウォーテーションの中にパイプ、リダイレクト単体 + /* 03 */ {2, {"hoge fuga", "piyo"}, -1, -1, R"(hoge\ fuga \pi\yo)", nullptr, nullptr}, + // tokenの中のバックスラッシュ + /* 04 */ {3, {"ho'ge", "fuga", "piyo"}, -1, -1, R"(ho\'ge fu"ga" pi'yo)", nullptr, nullptr}, + // token中のクウォーテーション、token中の\' + /* 05 */ {1, {"hoge fuga"}, -1, -1, R"('hoge fuga' "piyo)", &t5, nullptr}, + // 閉じていないクウォーテーション + /* 06 */ {2, {"hoge", "fugapiyo"}, -1, -1, R"(hoge fuga\ +piyo)", nullptr, nullptr}, + // token中の\,改行 + /* 07 */ {2, {"hoge", "fuga piyo"}, -1, -1, R"(hoge "fuga \ +piyo")", nullptr, nullptr}, + // ダブルクォート中のバックスラッシュ,改行 + /* 08 */ {2, {"hoge", "fuga\\ \npiyo"}, -1, -1, R"(hoge "fuga\ +piyo")", nullptr, nullptr}, + //ダブルクォート中のバックスラッシュ,スペース,改行 + }; + for (size_t i = 0; i < sizeof(tbl) / sizeof(tbl[0]); i++) { + printf("case %zd: `%s`\n", i, tbl[i].linebuf); + std::vector tokens; + int redir = -1, *p_redir = &redir; + int pipe = -1, *p_pipe = &pipe; + struct TokenizerInnerState *t = tbl[i].iis; + + t = tokenize(tbl[i].linebuf, tokens, p_redir, p_pipe, t); + // return val check + + if (!isTISsame(t, tbl[i].eis)) { printTIS(t); printTIS(tbl[i].eis); printf(" \e[38;5;9mERR: invalid return val\e[0m\n"); ret = -1; } + // size of tokens check + if (tokens.size() != tbl[i].expected) { + printf(" \e[38;5;9mERR: num of tokens. expected %d but %zu.\e[0m\n", tbl[i].expected, tokens.size()); + ret = -1; + } + // redir & pipe check + if (redir != tbl[i].redir) { printf(" `%d`, `%d`\n", tbl[i].redir, redir); printf(" \e[38;5;9mredir ERR\e[0m\n"); ret = -1; } + if (pipe != tbl[i].pipe) { printf(" \e[38;5;9mpipe ERR\e[0m\n"); ret = -1; } + // token check + for (size_t j = 0; j < tokens.size(); j++) { + printf(" cmp `%s`, `%s`\n", tbl[i].result[j], tokens[j].c_str()); + if (tokens[j].c_str() == NULL || tbl[i].result[j] == NULL) { printf(" \e[38;5;9mERR\e[0m\n");ret = -1; continue; } + if (strcmp(tokens[j].c_str(), tbl[i].result[j])) { + printf(" \e[38;5;9mERR\e[0m\n"); ret = -1; + } + } + } + return ret; +} diff --git a/kernel/tests/tokenizer_test.hpp b/kernel/tests/tokenizer_test.hpp new file mode 100644 index 000000000..bbb3c5435 --- /dev/null +++ b/kernel/tests/tokenizer_test.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include "../tokenizer.hpp" + +bool isTISsame(struct TokenizerInnerState *tis1, struct TokenizerInnerState *tis2); +void printTIS(struct TokenizerInnerState *tis); +int test_tokenize(); From e00d4f5782ef3e6a9ba1442f9ddc0c7422cf377d Mon Sep 17 00:00:00 2001 From: Ryosuke Date: Wed, 24 Aug 2022 15:15:09 +0900 Subject: [PATCH 03/31] =?UTF-8?q?=E9=96=A2=E6=95=B0=E5=90=8D=E3=81=AE?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/terminal.cpp | 2 +- kernel/tests/main.cpp | 2 +- kernel/tests/tokenizer_test.cpp | 8 ++++---- kernel/tokenizer.cpp | 4 ++-- kernel/tokenizer.hpp | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index e8b5a0479..f6bfbd8f6 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -319,7 +319,7 @@ Rectangle Terminal::InputKey( int redir_idx = -1, *p_redir = &redir_idx; int pipe_idx = -1, *p_pipe = &pipe_idx; struct TokenizerInnerState *t = nullptr; - t = tokenize(&linebuf_[0], tokens, p_redir, p_pipe, t); + t = Tokenize(&linebuf_[0], tokens, p_redir, p_pipe, t); if (t) { // input not end cursor_.x = 0; if (cursor_.y < kRows - 1) { diff --git a/kernel/tests/main.cpp b/kernel/tests/main.cpp index ce7b795d2..c8f0be63a 100644 --- a/kernel/tests/main.cpp +++ b/kernel/tests/main.cpp @@ -5,7 +5,7 @@ int main() { int ret = 0; printf("test: tokenizer\n"); - ret = ret | test_tokenize(); + ret = ret | TestTokenize(); if (ret) { printf("\e[38;5;9mERR\e[0m\n"); diff --git a/kernel/tests/tokenizer_test.cpp b/kernel/tests/tokenizer_test.cpp index 032163d14..76fb3a8eb 100644 --- a/kernel/tests/tokenizer_test.cpp +++ b/kernel/tests/tokenizer_test.cpp @@ -8,7 +8,7 @@ #include "../tokenizer.hpp" -bool isTISsame(struct TokenizerInnerState *tis1, struct TokenizerInnerState *tis2) { +bool IsTisSame(struct TokenizerInnerState *tis1, struct TokenizerInnerState *tis2) { if (tis1 == nullptr ^ tis2 == nullptr) { return false; } if (tis1 == nullptr && tis2 == nullptr) { return true; } if (tis1->last_state != tis2->last_state) { return false; } @@ -17,7 +17,7 @@ bool isTISsame(struct TokenizerInnerState *tis1, struct TokenizerInnerState *tis return true; } -void printTIS(struct TokenizerInnerState *tis) { +void PrintTis(struct TokenizerInnerState *tis) { std::cout << " >>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl; if (!tis) { std::cout << " nullptr" << std::endl; } else { @@ -29,7 +29,7 @@ void printTIS(struct TokenizerInnerState *tis) { std::cout << " <<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl; } -int test_tokenize() { +int TestTokenize() { int ret = 0; struct TokenizerInnerState t0 = { InToken, BackSlash, "hoge"}; struct TokenizerInnerState t5 = { InDoubleQuoted, Init, "piyo"}; @@ -76,7 +76,7 @@ piyo")", nullptr, nullptr}, t = tokenize(tbl[i].linebuf, tokens, p_redir, p_pipe, t); // return val check - if (!isTISsame(t, tbl[i].eis)) { printTIS(t); printTIS(tbl[i].eis); printf(" \e[38;5;9mERR: invalid return val\e[0m\n"); ret = -1; } + if (!isTISsame(t, tbl[i].eis)) { PrintTis(t); PrintTis(tbl[i].eis); printf(" \e[38;5;9mERR: invalid return val\e[0m\n"); ret = -1; } // size of tokens check if (tokens.size() != tbl[i].expected) { printf(" \e[38;5;9mERR: num of tokens. expected %d but %zu.\e[0m\n", tbl[i].expected, tokens.size()); diff --git a/kernel/tokenizer.cpp b/kernel/tokenizer.cpp index 07da23bd9..4d15b868d 100644 --- a/kernel/tokenizer.cpp +++ b/kernel/tokenizer.cpp @@ -3,7 +3,7 @@ #include #include -TokenizerInnerState *tokenize(const char *c, std::vector& tokens, +TokenizerInnerState *Tokenize(const char *c, std::vector& tokens, int *redir_idx, int *pipe_idx, TokenizerInnerState *last_istate) { State state = Init; State last_state = Init; @@ -114,4 +114,4 @@ TokenizerInnerState *tokenize(const char *c, std::vector& tokens, } else { return nullptr; } -} \ No newline at end of file +} diff --git a/kernel/tokenizer.hpp b/kernel/tokenizer.hpp index 4ea005a5b..1ea7ac93d 100644 --- a/kernel/tokenizer.hpp +++ b/kernel/tokenizer.hpp @@ -23,5 +23,5 @@ struct TokenizerInnerState { std::string tmp_token; }; -TokenizerInnerState *tokenize(const char *c, std::vector& tokens, - int *redir_idx, int *pipe_idx, TokenizerInnerState *last_istate); \ No newline at end of file +TokenizerInnerState *Tokenize(const char *c, std::vector& tokens, + int *redir_idx, int *pipe_idx, TokenizerInnerState *last_istate); From 74a2b91e7989d5fed4d45954736dcd34f495a0f8 Mon Sep 17 00:00:00 2001 From: Ryosuke Date: Wed, 24 Aug 2022 15:22:02 +0900 Subject: [PATCH 04/31] =?UTF-8?q?=E9=96=A2=E6=95=B0=E5=90=8D=E5=A4=89?= =?UTF-8?q?=E6=9B=B4=E3=81=AE=E9=81=A9=E5=BF=9C=E3=81=97=E5=BF=98=E3=82=8C?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/tests/tokenizer_test.cpp | 4 ++-- kernel/tests/tokenizer_test.hpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/tests/tokenizer_test.cpp b/kernel/tests/tokenizer_test.cpp index 76fb3a8eb..af6b7b5e2 100644 --- a/kernel/tests/tokenizer_test.cpp +++ b/kernel/tests/tokenizer_test.cpp @@ -73,10 +73,10 @@ piyo")", nullptr, nullptr}, int pipe = -1, *p_pipe = &pipe; struct TokenizerInnerState *t = tbl[i].iis; - t = tokenize(tbl[i].linebuf, tokens, p_redir, p_pipe, t); + t = Tokenize(tbl[i].linebuf, tokens, p_redir, p_pipe, t); // return val check - if (!isTISsame(t, tbl[i].eis)) { PrintTis(t); PrintTis(tbl[i].eis); printf(" \e[38;5;9mERR: invalid return val\e[0m\n"); ret = -1; } + if (!IsTisSame(t, tbl[i].eis)) { PrintTis(t); PrintTis(tbl[i].eis); printf(" \e[38;5;9mERR: invalid return val\e[0m\n"); ret = -1; } // size of tokens check if (tokens.size() != tbl[i].expected) { printf(" \e[38;5;9mERR: num of tokens. expected %d but %zu.\e[0m\n", tbl[i].expected, tokens.size()); diff --git a/kernel/tests/tokenizer_test.hpp b/kernel/tests/tokenizer_test.hpp index bbb3c5435..0d87552f8 100644 --- a/kernel/tests/tokenizer_test.hpp +++ b/kernel/tests/tokenizer_test.hpp @@ -2,6 +2,6 @@ #include "../tokenizer.hpp" -bool isTISsame(struct TokenizerInnerState *tis1, struct TokenizerInnerState *tis2); -void printTIS(struct TokenizerInnerState *tis); -int test_tokenize(); +bool IsTisSame(struct TokenizerInnerState *tis1, struct TokenizerInnerState *tis2); +void PrintTis(struct TokenizerInnerState *tis); +int TestTokenize(); From 730baa022aba571a7df0b4a154f4e88ac92e7f56 Mon Sep 17 00:00:00 2001 From: tomiy Date: Sun, 5 Mar 2023 22:49:51 +0900 Subject: [PATCH 05/31] fix memory leak --- kernel/terminal.cpp | 5 +++-- kernel/tokenizer.cpp | 7 ++++--- kernel/tokenizer.hpp | 5 +++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index f6bfbd8f6..9ec2ad384 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "font.hpp" #include "layer.hpp" @@ -318,8 +319,8 @@ Rectangle Terminal::InputKey( std::vector tokens; int redir_idx = -1, *p_redir = &redir_idx; int pipe_idx = -1, *p_pipe = &pipe_idx; - struct TokenizerInnerState *t = nullptr; - t = Tokenize(&linebuf_[0], tokens, p_redir, p_pipe, t); + std::unique_ptr t = nullptr; + t = Tokenize(&linebuf_[0], tokens, p_redir, p_pipe, std::move(t)); if (t) { // input not end cursor_.x = 0; if (cursor_.y < kRows - 1) { diff --git a/kernel/tokenizer.cpp b/kernel/tokenizer.cpp index 4d15b868d..0cb674594 100644 --- a/kernel/tokenizer.cpp +++ b/kernel/tokenizer.cpp @@ -2,9 +2,10 @@ #include #include +#include -TokenizerInnerState *Tokenize(const char *c, std::vector& tokens, - int *redir_idx, int *pipe_idx, TokenizerInnerState *last_istate) { +std::unique_ptr Tokenize(const char *c, std::vector& tokens, + int *redir_idx, int *pipe_idx, std::unique_ptr last_istate) { State state = Init; State last_state = Init; std::string tmp_token; @@ -105,7 +106,7 @@ TokenizerInnerState *Tokenize(const char *c, std::vector& tokens, } if (state != Init || (state == Init && last_state == BackSlash)) { if (!last_istate) { - last_istate = new TokenizerInnerState ; + last_istate = std::make_unique() ; } last_istate->state = state; last_istate->last_state = last_state; diff --git a/kernel/tokenizer.hpp b/kernel/tokenizer.hpp index 1ea7ac93d..ba9eb42f4 100644 --- a/kernel/tokenizer.hpp +++ b/kernel/tokenizer.hpp @@ -8,6 +8,7 @@ #include #include +#include enum State { Init, @@ -23,5 +24,5 @@ struct TokenizerInnerState { std::string tmp_token; }; -TokenizerInnerState *Tokenize(const char *c, std::vector& tokens, - int *redir_idx, int *pipe_idx, TokenizerInnerState *last_istate); +std::unique_ptr Tokenize(const char *c, std::vector& tokens, + int *redir_idx, int *pipe_idx, std::unique_ptr last_istate); From 97ad03f172197d12be598d7a21ad43bba4f57187 Mon Sep 17 00:00:00 2001 From: tomiy Date: Sun, 5 Mar 2023 23:30:35 +0900 Subject: [PATCH 06/31] =?UTF-8?q?=E4=B8=8D=E8=A6=81=E3=81=AA=E5=A4=89?= =?UTF-8?q?=E6=95=B0=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/terminal.cpp | 49 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index 9ec2ad384..85aee6088 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -317,10 +317,10 @@ Rectangle Terminal::InputKey( if (ascii == '\n') { linebuf_[linebuf_index_] = 0; std::vector tokens; - int redir_idx = -1, *p_redir = &redir_idx; - int pipe_idx = -1, *p_pipe = &pipe_idx; + int redir_idx = -1; + int pipe_idx = -1; std::unique_ptr t = nullptr; - t = Tokenize(&linebuf_[0], tokens, p_redir, p_pipe, std::move(t)); + t = Tokenize(&linebuf_[0], tokens, &redir_idx, &pipe_idx, std::move(t)); if (t) { // input not end cursor_.x = 0; if (cursor_.y < kRows - 1) { @@ -393,8 +393,7 @@ void Terminal::Scroll1() { } void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pipe_idx) { - std::string str_command = args[0]; - const char* command = str_command.c_str(); + std::string command = args[0]; auto original_stdout = files_[1]; int exit_code = 0; @@ -448,13 +447,13 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi (*layer_task_map)[layer_id_] = subtask_id; } - if (strcmp(command, ">") == 0) { + if (command == ">") { PrintToFD(*files_[2], "no command befoer > \n"); exit_code = 1; - } else if (strcmp(command, "|") == 0) { + } else if (command == "|") { PrintToFD(*files_[2], "no command befoer | \n"); exit_code = 1; - } else if (strcmp(command, "echo") == 0) { + } else if (command == "echo") { if (args.size() > 1) { if (args[1] == "$?") { PrintToFD(*files_[1], "%d", last_exit_code_); @@ -465,13 +464,13 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi } } PrintToFD(*files_[1], "\n"); - } else if (strcmp(command, "clear") == 0) { + } else if (command == "clear") { if (show_window_) { FillRectangle(*window_->InnerWriter(), {4, 4}, {8*kColumns, 16*kRows}, {0, 0, 0}); } cursor_.y = 0; - } else if (strcmp(command, "lspci") == 0) { + } else if (command == "lspci") { for (int i = 0; i < pci::num_device; ++i) { const auto& dev = pci::devices[i]; auto vendor_id = pci::ReadVendorId(dev.bus, dev.device, dev.function); @@ -480,7 +479,7 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi dev.bus, dev.device, dev.function, vendor_id, dev.header_type, dev.class_code.base, dev.class_code.sub, dev.class_code.interface); } - } else if (strcmp(command, "ls") == 0) { + } else if (command == "ls") { bool verbose = false; if (args.size() < 2) { ListAllEntries(*files_[1], fat::boot_volume_image->root_cluster, verbose); @@ -518,7 +517,7 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi } } - } else if (strcmp(command, "cat") == 0) { + } else if (command == "cat") { std::vector> fd_vec; if (args.size() < 2) { fd_vec.push_back(files_[0]); @@ -553,7 +552,7 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi DrawCursor(true); } } - } else if (strcmp(command, "noterm") == 0) { + } else if (command == "noterm") { char* first_arg = strchr(&linebuf_[0], ' '); auto term_desc = new TerminalDescriptor{ first_arg, true, false, files_ @@ -561,7 +560,7 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi task_manager->NewTask() .InitContext(TaskTerminal, reinterpret_cast(term_desc)) .Wakeup(); - } else if (strcmp(command, "memstat") == 0) { + } else if (command == "memstat") { const auto p_stat = memory_manager->Stat(); PrintToFD(*files_[1], "Phys used : %lu frames (%llu MiB)\n", p_stat.allocated_frames, @@ -569,7 +568,7 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi PrintToFD(*files_[1], "Phys total: %lu frames (%llu MiB)\n", p_stat.total_frames, p_stat.total_frames * kBytesPerFrame / 1024 / 1024); - } else if (strcmp(command, "date") == 0) { + } else if (command == "date") { EFI_TIME t; uefi_rt->GetTime(&t, nullptr); if (t.TimeZone == EFI_UNSPECIFIED_TIMEZONE) { @@ -584,11 +583,11 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi PrintToFD(*files_[1], "-%02d%02d\n", -t.TimeZone / 60, -t.TimeZone % 60); } } - } else if (strcmp(command, "reboot") == 0) { + } else if (command == "reboot") { uefi_rt->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, nullptr); - } else if (strcmp(command, "poweroff") == 0) { + } else if (command == "poweroff") { uefi_rt->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, nullptr); - } else if (strcmp(command, "lsusb") == 0) { + } else if (command == "lsusb") { auto devmgr = usb::xhci::controller->DeviceManager(); for (int slot = 1; slot < 256; ++slot) { auto dev = devmgr->FindBySlot(slot); @@ -603,7 +602,7 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi dev->DeviceDesc().device_sub_class, dev->DeviceDesc().device_protocol); } - } else if (strcmp(command, "usbtest") == 0) { + } else if (command == "usbtest") { [&]{ if (!usb::cdc::driver) { PrintToFD(*files_[2], "CDC device not exist\n"); @@ -629,7 +628,7 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi files_[1]->Write(buf.data(), recv_len); PrintToFD(*files_[1], "\n"); }(); - } else if (strcmp(command, "setbaud") == 0) { + } else if (command == "setbaud") { [&]{ usb::cdc::LineCoding line_coding{ 9600, @@ -657,7 +656,7 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi PrintToFD(*files_[2], "Setting baud rate to %u\n", line_coding.dte_rate); usb::cdc::driver->SetLineCoding(line_coding); }(); - } else if (strcmp(command, "comproc") == 0) { + } else if (command == "comproc") { [&]{ if (!usb::cdc::driver) { PrintToFD(*files_[2], "CDC device not exist\n"); @@ -707,13 +706,13 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi } PrintToFD(*files_[1], "exit_code=%d\n", code); }(); - } else if (command[0] != 0) { - auto file_entry = FindCommand(command); + } else if (!command.empty()) { + auto file_entry = FindCommand(command.c_str()); if (!file_entry) { - PrintToFD(*files_[2], "no such command: %s\n", command); + PrintToFD(*files_[2], "no such command: %s\n", command.c_str()); exit_code = 1; } else { - auto [ ec, err ] = ExecuteFile(*file_entry, command, args); + auto [ ec, err ] = ExecuteFile(*file_entry, command.c_str(), args); if (err) { PrintToFD(*files_[2], "failed to exec file: %s\n", err.Name()); exit_code = -ec; From c196367f1e67d37491d1366f537ab15afff3c0e2 Mon Sep 17 00:00:00 2001 From: tomiy Date: Mon, 6 Mar 2023 00:16:36 +0900 Subject: [PATCH 07/31] =?UTF-8?q?strcmp=E3=82=92=3D=3D=E3=81=AB=E7=BD=AE?= =?UTF-8?q?=E6=8F=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/terminal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index 85aee6088..459d8a5b4 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -484,7 +484,7 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi if (args.size() < 2) { ListAllEntries(*files_[1], fat::boot_volume_image->root_cluster, verbose); } else { - if (strcmp(args[1].c_str(), "-l") == 0) { + if (args[1] == "-l") { verbose = true; args.erase(args.begin() + 1); } From 11e14a4eb378e6dbae2bb7ed3b3affa88f921ccf Mon Sep 17 00:00:00 2001 From: tomiy Date: Thu, 9 Mar 2023 21:25:18 +0900 Subject: [PATCH 08/31] =?UTF-8?q?=E7=84=A1=E9=A7=84=E3=81=AA=E8=A1=8C?= =?UTF-8?q?=E3=82=921=E8=A1=8C=E3=81=AB=E3=81=BE=E3=81=A8=E3=82=81?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/terminal.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index 459d8a5b4..81c8de2da 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -319,8 +319,7 @@ Rectangle Terminal::InputKey( std::vector tokens; int redir_idx = -1; int pipe_idx = -1; - std::unique_ptr t = nullptr; - t = Tokenize(&linebuf_[0], tokens, &redir_idx, &pipe_idx, std::move(t)); + std::unique_ptr t = Tokenize(&linebuf_[0], tokens, &redir_idx, &pipe_idx, nullptr); if (t) { // input not end cursor_.x = 0; if (cursor_.y < kRows - 1) { From 55b952db9bbcd2b7327dd481755ecc902e9b10d3 Mon Sep 17 00:00:00 2001 From: tomiy Date: Thu, 9 Mar 2023 21:37:01 +0900 Subject: [PATCH 09/31] =?UTF-8?q?=E7=84=A1=E9=A7=84=E3=81=AAif=E6=96=87?= =?UTF-8?q?=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/terminal.cpp | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index 81c8de2da..8ffa31a37 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -487,32 +487,28 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi verbose = true; args.erase(args.begin() + 1); } - if (args.size() >= 2) { - for (int i = 1; i < args.size(); i++) { - const char* file_name = args[i].c_str(); - auto [ dir, post_slash ] = fat::FindFile(file_name); - if (dir == nullptr) { - PrintToFD(*files_[2], "No such file or directory: %s\n", file_name); + for (int i = 1; i < args.size(); i++) { + const char* file_name = args[i].c_str(); + auto [ dir, post_slash ] = fat::FindFile(file_name); + if (dir == nullptr) { + PrintToFD(*files_[2], "No such file or directory: %s\n", file_name); + exit_code = 1; + } else if (dir->attr == fat::Attribute::kDirectory) { + ListAllEntries(*files_[1], dir->FirstCluster(), verbose); + } else { + char name[13]; + fat::FormatName(*dir, name); + if (post_slash) { + PrintToFD(*files_[2], "%s is not a directory\n", name); exit_code = 1; - } else if (dir->attr == fat::Attribute::kDirectory) { - ListAllEntries(*files_[1], dir->FirstCluster(), verbose); } else { - char name[13]; - fat::FormatName(*dir, name); - if (post_slash) { - PrintToFD(*files_[2], "%s is not a directory\n", name); - exit_code = 1; + if (verbose) { + PrintFileAttr(*files_[1], *dir); } else { - if (verbose) { - PrintFileAttr(*files_[1], *dir); - } else { - PrintToFD(*files_[1], "%s\n", name); - } + PrintToFD(*files_[1], "%s\n", name); } } } - } else { - ListAllEntries(*files_[1], fat::boot_volume_image->root_cluster, verbose); } } From 4e2adf63002ec763481bbcee9433ecfc6dda832a Mon Sep 17 00:00:00 2001 From: tomiy Date: Thu, 9 Mar 2023 21:52:23 +0900 Subject: [PATCH 10/31] =?UTF-8?q?string=E3=81=AE=E9=95=B7=E3=81=95?= =?UTF-8?q?=E3=81=AE=E5=8F=96=E5=BE=97=E6=96=B9=E6=B3=95=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/terminal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index 8ffa31a37..b1d390cdf 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -607,7 +607,7 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi size_t send_len; if (args.size() < 2) { for (int i = 1; i < args.size(); i++) { - send_len = strlen(args[i].c_str()); + send_len = args[i].length(); usb::cdc::driver->SendSerial(args[i].c_str(), send_len); } } else { From fee03eabf562bf9a675fa577a17e917c7e94a391 Mon Sep 17 00:00:00 2001 From: tomiy Date: Thu, 9 Mar 2023 21:57:36 +0900 Subject: [PATCH 11/31] =?UTF-8?q?=E5=BC=95=E6=95=B0=E3=82=92=E6=94=B9?= =?UTF-8?q?=E8=A1=8C=E3=81=97=E3=81=9F=E7=AE=87=E6=89=80=E3=81=AE=E5=85=88?= =?UTF-8?q?=E9=A0=AD=E4=BD=8D=E7=BD=AE=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/terminal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index b1d390cdf..9570a0981 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -400,7 +400,7 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi if (redir_idx != -1 && redir_idx != 0) { if (args.size() < redir_idx + 2) { PrintToFD(*files_[2], - "failed to create a redirect file"); + "failed to create a redirect file"); return; } const char* redir_dest = args[redir_idx+1].c_str(); From 41056cf354410c3b6ddd599da85ccf546fe275f2 Mon Sep 17 00:00:00 2001 From: tomiy Date: Thu, 9 Mar 2023 22:23:24 +0900 Subject: [PATCH 12/31] =?UTF-8?q?=E5=88=97=E6=8C=99=E5=AD=90=E3=81=AE?= =?UTF-8?q?=E6=84=8F=E5=91=B3=E3=82=92=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=81=AB=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/tokenizer.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/tokenizer.hpp b/kernel/tokenizer.hpp index ba9eb42f4..3d6e5008f 100644 --- a/kernel/tokenizer.hpp +++ b/kernel/tokenizer.hpp @@ -11,11 +11,11 @@ #include enum State { - Init, - InToken, - InDoubleQuoted, - InSingleQuoted, - BackSlash, + Init, // 初期状態 + InToken, // 通常の文字を受理してトークンを処理している状態 + InDoubleQuoted, //ダブルクウォートを受理してトークンを処理している状態 + InSingleQuoted, // シングルクウォートを受理してトークンを処理している状態 + BackSlash, // バックスラッシュを受理した直後の状態 }; struct TokenizerInnerState { From 998e053230f9b4ab500b126a02ca0f330b93435c Mon Sep 17 00:00:00 2001 From: tomiy Date: Thu, 9 Mar 2023 22:38:14 +0900 Subject: [PATCH 13/31] =?UTF-8?q?=E3=83=A1=E3=83=B3=E3=83=90=E5=A4=89?= =?UTF-8?q?=E6=95=B0=E3=81=AE=E4=BB=95=E6=A7=98=E3=82=92=E3=82=B3=E3=83=A1?= =?UTF-8?q?=E3=83=B3=E3=83=88=E3=81=AB=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/tokenizer.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/tokenizer.hpp b/kernel/tokenizer.hpp index 3d6e5008f..1323a931a 100644 --- a/kernel/tokenizer.hpp +++ b/kernel/tokenizer.hpp @@ -19,9 +19,9 @@ enum State { }; struct TokenizerInnerState { - State state; - State last_state; - std::string tmp_token; + State state; // 現在の状態 + State last_state; // 1つ前の状態 + std::string tmp_token; // 現在受理している文字列 }; std::unique_ptr Tokenize(const char *c, std::vector& tokens, From a75639226c9a837717b383dea0deeb3e7ffdb7d4 Mon Sep 17 00:00:00 2001 From: tomiy Date: Thu, 9 Mar 2023 22:49:56 +0900 Subject: [PATCH 14/31] fix typo --- kernel/terminal.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index 9570a0981..6b0ab1eda 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -447,10 +447,10 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi } if (command == ">") { - PrintToFD(*files_[2], "no command befoer > \n"); + PrintToFD(*files_[2], "no command before > \n"); exit_code = 1; } else if (command == "|") { - PrintToFD(*files_[2], "no command befoer | \n"); + PrintToFD(*files_[2], "no command before | \n"); exit_code = 1; } else if (command == "echo") { if (args.size() > 1) { From bd6bf0f3f5609ba29cac3069f3ae0add1acce5b8 Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 10:28:34 +0900 Subject: [PATCH 15/31] =?UTF-8?q?=E9=96=A2=E6=95=B0=E5=90=8D=E3=81=AB?= =?UTF-8?q?=E5=90=AB=E3=81=BE=E3=82=8C=E3=82=8BTokenizerInnerState?= =?UTF-8?q?=E3=81=AE=E7=95=A5=E7=A7=B0Tis=E3=82=92TIS=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/tests/tokenizer_test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/tests/tokenizer_test.cpp b/kernel/tests/tokenizer_test.cpp index af6b7b5e2..98be619fb 100644 --- a/kernel/tests/tokenizer_test.cpp +++ b/kernel/tests/tokenizer_test.cpp @@ -8,7 +8,7 @@ #include "../tokenizer.hpp" -bool IsTisSame(struct TokenizerInnerState *tis1, struct TokenizerInnerState *tis2) { +bool IsTISSame(struct TokenizerInnerState *tis1, struct TokenizerInnerState *tis2) { if (tis1 == nullptr ^ tis2 == nullptr) { return false; } if (tis1 == nullptr && tis2 == nullptr) { return true; } if (tis1->last_state != tis2->last_state) { return false; } @@ -17,7 +17,7 @@ bool IsTisSame(struct TokenizerInnerState *tis1, struct TokenizerInnerState *tis return true; } -void PrintTis(struct TokenizerInnerState *tis) { +void PrintTIS(struct TokenizerInnerState *tis) { std::cout << " >>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl; if (!tis) { std::cout << " nullptr" << std::endl; } else { @@ -76,7 +76,7 @@ piyo")", nullptr, nullptr}, t = Tokenize(tbl[i].linebuf, tokens, p_redir, p_pipe, t); // return val check - if (!IsTisSame(t, tbl[i].eis)) { PrintTis(t); PrintTis(tbl[i].eis); printf(" \e[38;5;9mERR: invalid return val\e[0m\n"); ret = -1; } + if (!IsTISSame(t, tbl[i].eis)) { PrintTIS(t); PrintTIS(tbl[i].eis); printf(" \e[38;5;9mERR: invalid return val\e[0m\n"); ret = -1; } // size of tokens check if (tokens.size() != tbl[i].expected) { printf(" \e[38;5;9mERR: num of tokens. expected %d but %zu.\e[0m\n", tbl[i].expected, tokens.size()); From 06b5d3e6925fc486982b08c9926b4bbdb8ffb1ba Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 11:44:43 +0900 Subject: [PATCH 16/31] using c++17 --- kernel/tests/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/tests/Makefile b/kernel/tests/Makefile index e3c5327e5..c72e34e12 100644 --- a/kernel/tests/Makefile +++ b/kernel/tests/Makefile @@ -1,5 +1,5 @@ CFLAGS += -O2 -Wall -g -CXXFLAGS += -O2 -Wall -g +CPPFLAGS += -O2 -Wall -g -std=c++17 TARGET = tests OBJS = main.o tokenizer.o tokenizer_test.o From 31c05bfc18dd80eab7eec07a0a22c9cdcf60113a Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 11:46:57 +0900 Subject: [PATCH 17/31] =?UTF-8?q?TokenizerInnerState=E3=81=AB=E3=82=B3?= =?UTF-8?q?=E3=83=B3=E3=82=B9=E3=83=88=E3=83=A9=E3=82=AF=E3=82=BF=E3=81=A8?= =?UTF-8?q?unipue=5Fprt=E3=81=AE=E3=82=A8=E3=82=A4=E3=83=AA=E3=82=A2?= =?UTF-8?q?=E3=82=B9=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/tokenizer.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/tokenizer.hpp b/kernel/tokenizer.hpp index 1323a931a..8594e8504 100644 --- a/kernel/tokenizer.hpp +++ b/kernel/tokenizer.hpp @@ -22,7 +22,9 @@ struct TokenizerInnerState { State state; // 現在の状態 State last_state; // 1つ前の状態 std::string tmp_token; // 現在受理している文字列 + TokenizerInnerState(State state=Init, State last_state=Init, const char *tmp_token=""): state(state), last_state(last_state), tmp_token(tmp_token) {} }; +using tis_uniq = std::unique_ptr; -std::unique_ptr Tokenize(const char *c, std::vector& tokens, - int *redir_idx, int *pipe_idx, std::unique_ptr last_istate); +tis_uniq Tokenize(const char *c, std::vector& tokens, + int *redir_idx, int *pipe_idx, tis_uniq last_istate); From 66d2556a4a71529ad4ab0df00ecb853b88baed13 Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 11:48:37 +0900 Subject: [PATCH 18/31] =?UTF-8?q?=E6=A7=8B=E9=80=A0=E4=BD=93=E3=81=AE?= =?UTF-8?q?=E3=83=9D=E3=83=B3=E3=82=BF=E3=82=92unique=E3=83=9D=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E3=82=BF=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/tests/tokenizer_test.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/kernel/tests/tokenizer_test.cpp b/kernel/tests/tokenizer_test.cpp index 98be619fb..98a4c7b2d 100644 --- a/kernel/tests/tokenizer_test.cpp +++ b/kernel/tests/tokenizer_test.cpp @@ -8,7 +8,7 @@ #include "../tokenizer.hpp" -bool IsTISSame(struct TokenizerInnerState *tis1, struct TokenizerInnerState *tis2) { +bool IsTISSame(const std::unique_ptr &tis1, const std::unique_ptr &tis2) { if (tis1 == nullptr ^ tis2 == nullptr) { return false; } if (tis1 == nullptr && tis2 == nullptr) { return true; } if (tis1->last_state != tis2->last_state) { return false; } @@ -17,7 +17,7 @@ bool IsTISSame(struct TokenizerInnerState *tis1, struct TokenizerInnerState *tis return true; } -void PrintTIS(struct TokenizerInnerState *tis) { +void PrintTIS(const std::unique_ptr &tis) { std::cout << " >>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl; if (!tis) { std::cout << " nullptr" << std::endl; } else { @@ -31,22 +31,22 @@ void PrintTIS(struct TokenizerInnerState *tis) { int TestTokenize() { int ret = 0; - struct TokenizerInnerState t0 = { InToken, BackSlash, "hoge"}; - struct TokenizerInnerState t5 = { InDoubleQuoted, Init, "piyo"}; - struct TokenizerInnerState t2 = { Init, BackSlash, ""}; - struct TokenizerInnerState t9 = { InDoubleQuoted, Init, "ed> hoge"}; + auto t0 = std::make_unique(InToken, BackSlash, "hoge"); + auto t5 = std::make_unique(InDoubleQuoted, Init, "piyo"); + auto t2 = std::make_unique(Init, BackSlash, ""); + auto t9 = std::make_unique(InDoubleQuoted, Init, "ed> hoge"); struct { const int expected; const char* result[32]; int redir; int pipe; char linebuf[100]; - struct TokenizerInnerState *eis; // expected - struct TokenizerInnerState *iis; // input + std::unique_ptr eis; // expected + std::unique_ptr iis; // input } tbl[] = { /* 00 */ {9, {"hoge", "|", "fuga", "|", "piyo", ">", "foo", ">", "bar"}, 5, 1, R"(hoge |fuga| piyo >foo> bar)", nullptr, nullptr}, // パイプ, 空白の前後が空白、複数のリダイレクト - /* 01 */ {3, {"minied", "-p", "mini|ed>"}, -1, -1, R"(minied -p "mini|ed>" hoge\)", &t0, nullptr}, + /* 01 */ {3, {"minied", "-p", "mini|ed>"}, -1, -1, R"(minied -p "mini|ed>" hoge\)", std::move(t0), nullptr}, // ダブルクォート中のリダイレクト, パイプ、\終端 /* 02 */ {4, {"hoge", ">", "piyo", "|"}, -1, -1, R"(hoge ">" piyo '|')", nullptr, nullptr}, // クウォーテーションの中にパイプ、リダイレクト単体 @@ -54,7 +54,7 @@ int TestTokenize() { // tokenの中のバックスラッシュ /* 04 */ {3, {"ho'ge", "fuga", "piyo"}, -1, -1, R"(ho\'ge fu"ga" pi'yo)", nullptr, nullptr}, // token中のクウォーテーション、token中の\' - /* 05 */ {1, {"hoge fuga"}, -1, -1, R"('hoge fuga' "piyo)", &t5, nullptr}, + /* 05 */ {1, {"hoge fuga"}, -1, -1, R"('hoge fuga' "piyo)", std::move(t5), nullptr}, // 閉じていないクウォーテーション /* 06 */ {2, {"hoge", "fugapiyo"}, -1, -1, R"(hoge fuga\ piyo)", nullptr, nullptr}, @@ -71,9 +71,9 @@ piyo")", nullptr, nullptr}, std::vector tokens; int redir = -1, *p_redir = &redir; int pipe = -1, *p_pipe = &pipe; - struct TokenizerInnerState *t = tbl[i].iis; + auto t = std::move(tbl[i].iis); - t = Tokenize(tbl[i].linebuf, tokens, p_redir, p_pipe, t); + t = Tokenize(tbl[i].linebuf, tokens, p_redir, p_pipe, std::move(t)); // return val check if (!IsTISSame(t, tbl[i].eis)) { PrintTIS(t); PrintTIS(tbl[i].eis); printf(" \e[38;5;9mERR: invalid return val\e[0m\n"); ret = -1; } From 701d7722f1fab9f1e4d5c6d42cc96691547353c2 Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 12:01:20 +0900 Subject: [PATCH 19/31] use dep file --- kernel/tests/Makefile | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/kernel/tests/Makefile b/kernel/tests/Makefile index c72e34e12..683af640f 100644 --- a/kernel/tests/Makefile +++ b/kernel/tests/Makefile @@ -1,22 +1,22 @@ CFLAGS += -O2 -Wall -g -CPPFLAGS += -O2 -Wall -g -std=c++17 +CPPFLAGS += -O2 -Wall -g -std=c++17 -MMD -MP -MF $(@:.o=.d) TARGET = tests -OBJS = main.o tokenizer.o tokenizer_test.o +VPATH = ../ +SRC = main.cpp tokenizer.cpp tokenizer_test.cpp +OBJS = $(SRC:.cpp=.o) +DEPS = $(SRC:.cpp=.d) .PHONY: all all: $(TARGET) .PHONY: clean clean: - rm -rf *.o $(TARGET) + rm -rf *.o $(TARGET) $(DEPS) $(TARGET): $(OBJS) Makefile clang++ $(LDFLAGS) -o $@ $(OBJS) -fuse-ld=lld -tokenizer.o: ../tokenizer.cpp Makefile - clang++ $(CPPFLAGS) $(CFLAGS) -c $< -o $@ - %.o: %.cpp Makefile clang++ $(CPPFLAGS) $(CFLAGS) -c $< -o $@ @@ -24,3 +24,5 @@ tokenizer.o: ../tokenizer.cpp Makefile test: $(TARGET) ./$(TARGET) +-include $(DEPS) +.SECONDARY: $(OBJS) From 41f7811a34b33676758e4ad455f4898140bc448c Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 13:19:37 +0900 Subject: [PATCH 20/31] =?UTF-8?q?TestTokenize=E3=81=AE=E6=88=BB=E3=82=8A?= =?UTF-8?q?=E5=80=A4=E3=82=92bool=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/tests/tokenizer_test.cpp | 16 ++++++++-------- kernel/tests/tokenizer_test.hpp | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/kernel/tests/tokenizer_test.cpp b/kernel/tests/tokenizer_test.cpp index 98a4c7b2d..cc62d0d9d 100644 --- a/kernel/tests/tokenizer_test.cpp +++ b/kernel/tests/tokenizer_test.cpp @@ -29,8 +29,8 @@ void PrintTIS(const std::unique_ptr &tis) { std::cout << " <<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl; } -int TestTokenize() { - int ret = 0; +bool TestTokenize() { + bool ret = true; auto t0 = std::make_unique(InToken, BackSlash, "hoge"); auto t5 = std::make_unique(InDoubleQuoted, Init, "piyo"); auto t2 = std::make_unique(Init, BackSlash, ""); @@ -76,21 +76,21 @@ piyo")", nullptr, nullptr}, t = Tokenize(tbl[i].linebuf, tokens, p_redir, p_pipe, std::move(t)); // return val check - if (!IsTISSame(t, tbl[i].eis)) { PrintTIS(t); PrintTIS(tbl[i].eis); printf(" \e[38;5;9mERR: invalid return val\e[0m\n"); ret = -1; } + if (!IsTISSame(t, tbl[i].eis)) { PrintTIS(t); PrintTIS(tbl[i].eis); printf(" \e[38;5;9mERR: invalid return val\e[0m\n"); ret = false; } // size of tokens check if (tokens.size() != tbl[i].expected) { printf(" \e[38;5;9mERR: num of tokens. expected %d but %zu.\e[0m\n", tbl[i].expected, tokens.size()); - ret = -1; + ret = false; } // redir & pipe check - if (redir != tbl[i].redir) { printf(" `%d`, `%d`\n", tbl[i].redir, redir); printf(" \e[38;5;9mredir ERR\e[0m\n"); ret = -1; } - if (pipe != tbl[i].pipe) { printf(" \e[38;5;9mpipe ERR\e[0m\n"); ret = -1; } + if (redir != tbl[i].redir) { printf(" `%d`, `%d`\n", tbl[i].redir, redir); printf(" \e[38;5;9mredir ERR\e[0m\n"); ret = false; } + if (pipe != tbl[i].pipe) { printf(" \e[38;5;9mpipe ERR\e[0m\n"); ret = false; } // token check for (size_t j = 0; j < tokens.size(); j++) { printf(" cmp `%s`, `%s`\n", tbl[i].result[j], tokens[j].c_str()); - if (tokens[j].c_str() == NULL || tbl[i].result[j] == NULL) { printf(" \e[38;5;9mERR\e[0m\n");ret = -1; continue; } + if (tokens[j].c_str() == NULL || tbl[i].result[j] == NULL) { printf(" \e[38;5;9mERR\e[0m\n");ret = false; continue; } if (strcmp(tokens[j].c_str(), tbl[i].result[j])) { - printf(" \e[38;5;9mERR\e[0m\n"); ret = -1; + printf(" \e[38;5;9mERR\e[0m\n"); ret = false; } } } diff --git a/kernel/tests/tokenizer_test.hpp b/kernel/tests/tokenizer_test.hpp index 0d87552f8..807084a44 100644 --- a/kernel/tests/tokenizer_test.hpp +++ b/kernel/tests/tokenizer_test.hpp @@ -4,4 +4,4 @@ bool IsTisSame(struct TokenizerInnerState *tis1, struct TokenizerInnerState *tis2); void PrintTis(struct TokenizerInnerState *tis); -int TestTokenize(); +bool TestTokenize(); From e3de4276d338d443d3180b1d826bc8cda9b16406 Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 13:22:05 +0900 Subject: [PATCH 21/31] =?UTF-8?q?=E3=83=86=E3=82=B9=E3=83=88=E3=81=AE?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E5=89=B2=E5=90=88=E3=82=92=E8=A1=A8=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/tests/main.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/kernel/tests/main.cpp b/kernel/tests/main.cpp index c8f0be63a..785f89d03 100644 --- a/kernel/tests/main.cpp +++ b/kernel/tests/main.cpp @@ -1,17 +1,22 @@ +#include #include "tokenizer_test.hpp" int main() { - int ret = 0; + const int test_num = 1; + int success = 0; - printf("test: tokenizer\n"); - ret = ret | TestTokenize(); + std::cout << "test: tokenizer" << std::endl; + if (TestTokenize()) { + success++; + } - if (ret) { - printf("\e[38;5;9mERR\e[0m\n"); + std::cout << "test: " << success << "/" << test_num << " passed" << std::endl; + if (test_num == success) { + std::cout << "\e[38;5;10mOK\e[0m\n" << std::endl; + return 0; } else { - printf("\e[38;5;10mOK\e[0m\n"); + std::cout << "\e[38;5;9mERR\e[0m\n" << std::endl; + return -1; } - - return ret; } From 2f279f6da781a0d8ed1d3d8e7bf7227f2912ddf2 Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 14:47:15 +0900 Subject: [PATCH 22/31] =?UTF-8?q?=E5=BC=95=E6=95=B0=E3=81=AE=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E3=83=87=E3=83=B3=E3=83=88=E3=83=AC=E3=83=99=E3=83=AB?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/tokenizer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/tokenizer.cpp b/kernel/tokenizer.cpp index 0cb674594..f1d392bb1 100644 --- a/kernel/tokenizer.cpp +++ b/kernel/tokenizer.cpp @@ -5,7 +5,8 @@ #include std::unique_ptr Tokenize(const char *c, std::vector& tokens, - int *redir_idx, int *pipe_idx, std::unique_ptr last_istate) { + int *redir_idx, int *pipe_idx, + std::unique_ptr last_istate) { State state = Init; State last_state = Init; std::string tmp_token; From 3a4d3cd029eab183b14086ac5333a5834629df59 Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 15:13:15 +0900 Subject: [PATCH 23/31] =?UTF-8?q?tmp=5Ftoken=E3=81=8Cstring=E3=81=AE?= =?UTF-8?q?=E3=82=B3=E3=83=B3=E3=82=B9=E3=83=88=E3=83=A9=E3=82=AF=E3=82=BF?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/tokenizer.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/tokenizer.hpp b/kernel/tokenizer.hpp index 8594e8504..8203c975b 100644 --- a/kernel/tokenizer.hpp +++ b/kernel/tokenizer.hpp @@ -23,6 +23,7 @@ struct TokenizerInnerState { State last_state; // 1つ前の状態 std::string tmp_token; // 現在受理している文字列 TokenizerInnerState(State state=Init, State last_state=Init, const char *tmp_token=""): state(state), last_state(last_state), tmp_token(tmp_token) {} + TokenizerInnerState(State state=Init, State last_state=Init, const std::string tmp_token=""): state(state), last_state(last_state), tmp_token(tmp_token) {} }; using tis_uniq = std::unique_ptr; From 7522e04db967892691d524357a525a5937190c36 Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 15:17:19 +0900 Subject: [PATCH 24/31] =?UTF-8?q?=E5=BC=95=E6=95=B0=E3=82=92=E5=A4=89?= =?UTF-8?q?=E6=9B=B4=E3=81=97=E3=81=AA=E3=81=84=E5=AE=9F=E8=A3=85=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4=E3=81=97=E3=80=81=E3=81=9D=E3=81=AE=E5=BC=95?= =?UTF-8?q?=E6=95=B0=E3=81=ABconst=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/tokenizer.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/kernel/tokenizer.cpp b/kernel/tokenizer.cpp index f1d392bb1..40a17988a 100644 --- a/kernel/tokenizer.cpp +++ b/kernel/tokenizer.cpp @@ -6,7 +6,7 @@ std::unique_ptr Tokenize(const char *c, std::vector& tokens, int *redir_idx, int *pipe_idx, - std::unique_ptr last_istate) { + const std::unique_ptr last_istate) { State state = Init; State last_state = Init; std::string tmp_token; @@ -106,13 +106,7 @@ std::unique_ptr Tokenize(const char *c, std::vector() ; - } - last_istate->state = state; - last_istate->last_state = last_state; - last_istate->tmp_token = tmp_token; - return last_istate; + return std::make_unique(state, last_state, tmp_token); } else { return nullptr; } From 630092bf74048b9f16bfaaaf7a3cec65f04a0ccf Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 15:29:08 +0900 Subject: [PATCH 25/31] =?UTF-8?q?verbose=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/tests/main.cpp | 5 +++-- kernel/tests/tokenizer_test.cpp | 22 ++++++++++++++-------- kernel/tests/tokenizer_test.hpp | 2 +- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/kernel/tests/main.cpp b/kernel/tests/main.cpp index 785f89d03..994acf9f8 100644 --- a/kernel/tests/main.cpp +++ b/kernel/tests/main.cpp @@ -5,9 +5,10 @@ int main() { const int test_num = 1; int success = 0; + const bool verbose = false; - std::cout << "test: tokenizer" << std::endl; - if (TestTokenize()) { + if (verbose) std::cout << "test: tokenizer" << std::endl; + if (TestTokenize(verbose)) { success++; } diff --git a/kernel/tests/tokenizer_test.cpp b/kernel/tests/tokenizer_test.cpp index cc62d0d9d..7277d5d73 100644 --- a/kernel/tests/tokenizer_test.cpp +++ b/kernel/tests/tokenizer_test.cpp @@ -29,7 +29,7 @@ void PrintTIS(const std::unique_ptr &tis) { std::cout << " <<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl; } -bool TestTokenize() { +bool TestTokenize(bool verbose) { bool ret = true; auto t0 = std::make_unique(InToken, BackSlash, "hoge"); auto t5 = std::make_unique(InDoubleQuoted, Init, "piyo"); @@ -67,7 +67,7 @@ piyo")", nullptr, nullptr}, //ダブルクォート中のバックスラッシュ,スペース,改行 }; for (size_t i = 0; i < sizeof(tbl) / sizeof(tbl[0]); i++) { - printf("case %zd: `%s`\n", i, tbl[i].linebuf); + if (verbose) printf("case %zd: `%s`\n", i, tbl[i].linebuf); std::vector tokens; int redir = -1, *p_redir = &redir; int pipe = -1, *p_pipe = &pipe; @@ -79,18 +79,24 @@ piyo")", nullptr, nullptr}, if (!IsTISSame(t, tbl[i].eis)) { PrintTIS(t); PrintTIS(tbl[i].eis); printf(" \e[38;5;9mERR: invalid return val\e[0m\n"); ret = false; } // size of tokens check if (tokens.size() != tbl[i].expected) { - printf(" \e[38;5;9mERR: num of tokens. expected %d but %zu.\e[0m\n", tbl[i].expected, tokens.size()); + if (verbose) printf(" \e[38;5;9mERR: num of tokens. expected %d but %zu.\e[0m\n", tbl[i].expected, tokens.size()); ret = false; } // redir & pipe check - if (redir != tbl[i].redir) { printf(" `%d`, `%d`\n", tbl[i].redir, redir); printf(" \e[38;5;9mredir ERR\e[0m\n"); ret = false; } - if (pipe != tbl[i].pipe) { printf(" \e[38;5;9mpipe ERR\e[0m\n"); ret = false; } + if (redir != tbl[i].redir) { + if (verbose) { + printf(" `%d`, `%d`\n", tbl[i].redir, redir); + printf(" \e[38;5;9mredir ERR\e[0m\n"); + } + ret = false; + } + if (pipe != tbl[i].pipe) { if (verbose) printf(" \e[38;5;9mpipe ERR\e[0m\n"); ret = false; } // token check for (size_t j = 0; j < tokens.size(); j++) { - printf(" cmp `%s`, `%s`\n", tbl[i].result[j], tokens[j].c_str()); - if (tokens[j].c_str() == NULL || tbl[i].result[j] == NULL) { printf(" \e[38;5;9mERR\e[0m\n");ret = false; continue; } + if (verbose) printf(" cmp `%s`, `%s`\n", tbl[i].result[j], tokens[j].c_str()); + if (tokens[j].c_str() == NULL || tbl[i].result[j] == NULL) { if (verbose) printf(" \e[38;5;9mERR\e[0m\n");ret = false; continue; } if (strcmp(tokens[j].c_str(), tbl[i].result[j])) { - printf(" \e[38;5;9mERR\e[0m\n"); ret = false; + if (verbose) printf(" \e[38;5;9mERR\e[0m\n"); ret = false; } } } diff --git a/kernel/tests/tokenizer_test.hpp b/kernel/tests/tokenizer_test.hpp index 807084a44..fefa1976d 100644 --- a/kernel/tests/tokenizer_test.hpp +++ b/kernel/tests/tokenizer_test.hpp @@ -4,4 +4,4 @@ bool IsTisSame(struct TokenizerInnerState *tis1, struct TokenizerInnerState *tis2); void PrintTis(struct TokenizerInnerState *tis); -bool TestTokenize(); +bool TestTokenize(bool verbose); From cf37d706c849d2cb928bc473e945c95e68ff9f75 Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 15:38:32 +0900 Subject: [PATCH 26/31] =?UTF-8?q?=E9=96=A2=E6=95=B0=E3=83=89=E3=82=AD?= =?UTF-8?q?=E3=83=A5=E3=83=A1=E3=83=B3=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/terminal.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index 6b0ab1eda..59dbaea79 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -391,6 +391,20 @@ void Terminal::Scroll1() { {4, 4 + 16*cursor_.y}, {8*kColumns, 16}, {0, 0, 0}); } +/** +* Terminal::ExecuteLine +* +* リダイレクトが複数含まれる場合、最初のリダイレクトのに有効となる +* リダイレクト以降の内容は処理しない簡易な実装となっているため、 +* コマンドの最後に書く必要がある。 +* リダイレクトを先頭に書くことはできない。 +* +* @param[in] args ターミナルの入力をtokenに分割したもの +* @param[in] redir_idx リダイレクト'>'が最初に登場するargsのインデックス +* argsにリダイレクトが含まれない場合-1 +* @param[in] pipe_idx パイプ'|'が最初に登場するargsのインデックス +* argsにパイプが含まれない場合-1 +*/ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pipe_idx) { std::string command = args[0]; From 3a45705bc0856dbc2b7909a676f54c34ac12ed2f Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 15:47:24 +0900 Subject: [PATCH 27/31] =?UTF-8?q?=E9=96=A2=E6=95=B0=E3=83=89=E3=82=AD?= =?UTF-8?q?=E3=83=A5=E3=83=A1=E3=83=B3=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/tokenizer.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/kernel/tokenizer.cpp b/kernel/tokenizer.cpp index 40a17988a..7e5b6aa8b 100644 --- a/kernel/tokenizer.cpp +++ b/kernel/tokenizer.cpp @@ -4,6 +4,27 @@ #include #include +/** +* Tokenize +* +* ターミナルが受け取った文字列をtokenizeする +* +* @param[in] *c ターミナルからの入力文字列 +* @param[out] tokens tokenを格納するvector +* @param[out] *redir_idx リダイレクト文字'>'が最初に登場するtokenのインデックス + tokenize未完了から続きをtokenizeする場合には、Tokenizeが返した値、 + 新たにtokenizeする場合-1を初期値とする +* @param[out] *pipe_idx パイプ文字'|'が最初に登場するtokenのインデックス + tokenize未完了から続きをtokenizeする場合には、Tokenizeが返した値、 + 新たにtokenizeする場合-1を初期値とする +* @param[in] last_state 前にtokenizeが完了しなかった時の、前のTokenizerの内部状態 + tokenize未完了から続きをtokenizeする場合には、Tokenizeが返した値、 + 新たにtokenizeする場合nullptrを初期値とする +* @return std::unique_ptr 入力が完全でtokenizeが完了した場合 +* nullptr, tokenizeが完了しなかった場合 +* Tokenizerの内部状態を返す +*/ + std::unique_ptr Tokenize(const char *c, std::vector& tokens, int *redir_idx, int *pipe_idx, const std::unique_ptr last_istate) { From 41e852b1dde56e515c1a86d5fd866d78aa4a1105 Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 15:55:00 +0900 Subject: [PATCH 28/31] =?UTF-8?q?=E5=A4=89=E6=9B=B4=E3=81=97=E3=81=AA?= =?UTF-8?q?=E3=81=84=E5=BC=95=E6=95=B0=E3=82=92const=E5=8F=82=E7=85=A7?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/terminal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index 59dbaea79..76e27a7b0 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -25,7 +25,7 @@ namespace { -WithError MakeArgVector(std::vector args, +WithError MakeArgVector(const std::vector &args, char** argv, int argv_len, char* argbuf, int argbuf_len) { int argc = 0; int argbuf_index = 0; From 5917e7d6d011547588dc860d9edea10d66b4c292 Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 17:14:43 +0900 Subject: [PATCH 29/31] =?UTF-8?q?=E5=89=8A=E9=99=A4=E3=81=95=E3=82=8C?= =?UTF-8?q?=E3=81=9F=E9=A0=98=E5=9F=9F=E3=82=92=E6=8C=87=E3=81=99=E3=83=9D?= =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=82=BF=E3=82=92=E7=94=9F=E6=88=90=E3=81=99?= =?UTF-8?q?=E3=82=8B=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/terminal.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index 76e27a7b0..96df20723 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -417,7 +417,8 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi "failed to create a redirect file"); return; } - const char* redir_dest = args[redir_idx+1].c_str(); + char redir_dest[12]; // maximum file name size of FAT (8.3 format) is = 12 + args[redir_idx+1].copy(redir_dest, 12); args.erase(args.begin() + redir_idx, args.end()); auto [ file, post_slash ] = fat::FindFile(redir_dest); From b9164c002583e71e490bdb9438503e777307df38 Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 17:25:22 +0900 Subject: [PATCH 30/31] =?UTF-8?q?strchr=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/terminal.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index 96df20723..689771286 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -441,10 +441,13 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi uint64_t subtask_id = 0; if (pipe_idx != -1 && pipe_idx != 0) { + std::string pipe_char = ""; + for(auto s = args.begin()+pipe_idx + 1; s != args.end(); ++s) { + pipe_char += *s; + } args.erase(args.begin() + pipe_idx-1, args.end()); - char* pipe_char = strchr(&linebuf_[0], '|'); - char* subcommand = &pipe_char[1]; + const char* subcommand = pipe_char.c_str(); auto& subtask = task_manager->NewTask(); pipe_fd = std::make_shared(subtask); @@ -563,7 +566,11 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi } } } else if (command == "noterm") { - char* first_arg = strchr(&linebuf_[0], ' '); + std::string first_arg = ""; + for(auto s = args.begin() + 1; s != args.end(); ++s) { + first_arg += *s; + } + auto term_desc = new TerminalDescriptor{ first_arg, true, false, files_ }; From ab09297756e5eac977d5819f672dd601c82592e3 Mon Sep 17 00:00:00 2001 From: tomiy Date: Tue, 22 Aug 2023 18:11:01 +0900 Subject: [PATCH 31/31] =?UTF-8?q?cat=20=E3=81=AE=E8=A4=87=E6=95=B0?= =?UTF-8?q?=E3=81=AE=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E5=AF=BE=E5=BF=9C?= =?UTF-8?q?=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/terminal.cpp | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp index 689771286..8e31a13a1 100644 --- a/kernel/terminal.cpp +++ b/kernel/terminal.cpp @@ -531,14 +531,13 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi } } else if (command == "cat") { - std::vector> fd_vec; + std::shared_ptr fd; if (args.size() < 2) { - fd_vec.push_back(files_[0]); + fd = files_[0]; } else { - for (int i = 1; i < args.size(); i++) { - auto [ file_entry, post_slash ] = fat::FindFile(args[i].c_str()); + auto [ file_entry, post_slash ] = fat::FindFile(args[1].c_str()); if (!file_entry) { - PrintToFD(*files_[2], "no such file: %s\n", args[i].c_str()); + PrintToFD(*files_[2], "no such file: %s\n", args[1].c_str()); exit_code = 1; } else if (file_entry->attr != fat::Attribute::kDirectory && post_slash) { char name[13]; @@ -546,24 +545,20 @@ void Terminal::ExecuteLine(std::vector& args, int redir_idx, int pi PrintToFD(*files_[2], "%s is not a directory\n", name); exit_code = 1; } else { - fd_vec.push_back(std::make_shared(*file_entry)); + fd = std::make_shared(*file_entry); } - } } - for (int i = 0; i < fd_vec.size(); i++) { - auto fd = fd_vec[i]; - if (fd) { - char u8buf[1024]; - DrawCursor(false); - while (true) { - size_t read_size = ReadDelim(*fd, '\n', u8buf, sizeof(u8buf)); - if (read_size == 0) { - break; - } - files_[1]->Write(u8buf, read_size); + if (fd) { + char u8buf[1024]; + DrawCursor(false); + while (true) { + size_t read_size = ReadDelim(*fd, '\n', u8buf, sizeof(u8buf)); + if (read_size == 0) { + break; } - DrawCursor(true); + files_[1]->Write(u8buf, read_size); } + DrawCursor(true); } } else if (command == "noterm") { std::string first_arg = "";