| 11 | #define ERROR_RETURN(__msg, __ret) do { perror(__msg); return __ret; } while (false) |
| 12 | |
| 13 | void Builtin::initialize() |
| 14 | { |
| 15 | MUST(m_builtin_commands.emplace("clear"_sv, |
| 16 | [](Execute&, BAN::Span<const BAN::String>, FILE*, FILE* fout) -> int |
| 17 | { |
| 18 | fprintf(fout, "\e[H\e[3J\e[2J"); |
| 19 | fflush(fout); |
| 20 | return 0; |
| 21 | }, true |
| 22 | )); |
| 23 | |
| 24 | MUST(m_builtin_commands.emplace("exit"_sv, |
| 25 | [](Execute&, BAN::Span<const BAN::String> arguments, FILE*, FILE*) -> int |
| 26 | { |
| 27 | int exit_code = 0; |
| 28 | if (arguments.size() > 1) |
| 29 | { |
| 30 | auto exit_string = arguments[1].sv(); |
| 31 | for (size_t i = 0; i < exit_string.size() && isdigit(exit_string[i]); i++) |
| 32 | exit_code = (exit_code * 10) + (exit_string[i] - '0'); |
| 33 | } |
| 34 | exit(exit_code); |
| 35 | ASSERT_NOT_REACHED(); |
| 36 | }, true |
| 37 | )); |
| 38 | |
| 39 | MUST(m_builtin_commands.emplace("exec"_sv, |
| 40 | [](Execute&, BAN::Span<const BAN::String> arguments, FILE*, FILE*) -> int |
| 41 | { |
| 42 | if (arguments.size() <= 1) |
| 43 | return 0; |
| 44 | |
| 45 | BAN::Vector<const char*> argv; |
| 46 | for (size_t i = 1; i < arguments.size(); i++) |
| 47 | MUST(argv.push_back(arguments[i].data())); |
| 48 | MUST(argv.push_back(nullptr)); |
| 49 | |
| 50 | execvp(argv[0], const_cast<char* const*>(argv.data())); |
| 51 | exit(128 + errno); |
| 52 | ASSERT_NOT_REACHED(); |
| 53 | }, true |
| 54 | )); |
| 55 | |
| 56 | MUST(m_builtin_commands.emplace("export"_sv, |
| 57 | [](Execute&, BAN::Span<const BAN::String> arguments, FILE*, FILE*) -> int |
| 58 | { |
| 59 | for (size_t i = 1; i < arguments.size(); i++) |
| 60 | { |
| 61 | const auto argument = arguments[i].sv(); |
| 62 | |
| 63 | const auto idx = argument.find('='); |
| 64 | if (!idx.has_value()) |
| 65 | continue; |
| 66 | |
| 67 | auto name = BAN::String(argument.substring(0, idx.value())); |
| 68 | const char* value = argument.data() + idx.value() + 1; |
| 69 | if (setenv(name.data(), value, true) == -1) |
| 70 | ERROR_RETURN("setenv", 1); |
no test coverage detected