120 lines
2.4 KiB
C++
120 lines
2.4 KiB
C++
#include "Builtin.h"
|
|
#include "Execute.h"
|
|
#include "Input.h"
|
|
#include "TokenParser.h"
|
|
|
|
#include <signal.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
int g_pid;
|
|
int g_argc;
|
|
char** g_argv;
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
g_pid = getpid();
|
|
g_argc = argc;
|
|
g_argv = argv;
|
|
|
|
{
|
|
struct sigaction sa;
|
|
sa.sa_flags = 0;
|
|
|
|
sa.sa_handler = [](int) {};
|
|
sigaction(SIGINT, &sa, nullptr);
|
|
|
|
sa.sa_handler = SIG_IGN;
|
|
sigaction(SIGTTOU, &sa, nullptr);
|
|
}
|
|
|
|
Builtin::get().initialize();
|
|
|
|
for (int i = 1; i < argc; i++)
|
|
{
|
|
if (argv[i][0] != '-')
|
|
{
|
|
g_argc = g_argc - i;
|
|
g_argv = g_argv + i;
|
|
|
|
Execute execute;
|
|
(void)execute.source_script(argv[i]);
|
|
return execute.last_return_value();
|
|
}
|
|
|
|
if (strcmp(argv[i], "-c") == 0)
|
|
{
|
|
if (i + 1 >= argc)
|
|
{
|
|
printf("-c requires an argument\n");
|
|
return 1;
|
|
}
|
|
|
|
g_argc = g_argc - (i + 2);
|
|
g_argv = g_argv + (i + 2);
|
|
|
|
bool got_input = false;
|
|
|
|
TokenParser parser(
|
|
[&](BAN::Optional<BAN::StringView>) -> BAN::Optional<BAN::String>
|
|
{
|
|
if (got_input)
|
|
return {};
|
|
got_input = true;
|
|
|
|
BAN::String input;
|
|
MUST(input.append(argv[i + 1]));
|
|
return input;
|
|
}
|
|
);
|
|
if (!parser.main_loop(true))
|
|
return 126;
|
|
return parser.execute().last_return_value();
|
|
}
|
|
else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0)
|
|
{
|
|
printf("banan-sh 1.0\n");
|
|
return 0;
|
|
}
|
|
else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
|
|
{
|
|
printf("usage: %s [options...]\n", argv[0]);
|
|
printf(" -c run following argument as an argument\n");
|
|
printf(" -v, --version print version information and exit\n");
|
|
printf(" -h, --help print this message and exit\n");
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
printf("unknown argument '%s'\n", argv[i]);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
Input input;
|
|
TokenParser parser(
|
|
[&](BAN::Optional<BAN::StringView> prompt) -> BAN::Optional<BAN::String>
|
|
{
|
|
return input.get_input(prompt);
|
|
}
|
|
);
|
|
|
|
if (const char* home_env = getenv("HOME"))
|
|
{
|
|
BAN::String config_file_path;
|
|
MUST(config_file_path.append(home_env));
|
|
MUST(config_file_path.append("/.shellrc"_sv));
|
|
|
|
struct stat st;
|
|
if (stat(config_file_path.data(), &st) == 0)
|
|
{
|
|
if (auto ret = parser.execute().source_script(config_file_path.sv()); ret.is_error())
|
|
fprintf(stderr, "could not source config file at '%s': %s\n", config_file_path.data(), ret.error().get_message());
|
|
}
|
|
}
|
|
|
|
if (!parser.main_loop(false))
|
|
return 126;
|
|
return 0;
|
|
}
|