42_KFS/src/shell/exec.c

116 lines
2.2 KiB
C

#include "kprintf.h"
#include "shell.h"
#include "string.h"
#include "terminal.h"
extern struct screen *screen;
static CMD_TOK find_command(char *line)
{
size_t i = 0;
bool uwu = false;
CMD_TOK command = ERROR;
if (!line[0])
return command;
while (line[i]) {
if (line[i] == ' ') {
uwu = true;
break;
}
i++;
}
line[i] = '\0';
if (!strcmp(line, "help"))
command = HELP;
else if (!strcmp(line, "reboot"))
command = REBOOT;
else if (!strcmp(line, "poweroff"))
command = POWEROFF;
else if (!strcmp(line, "echo"))
command = ECHO;
else if (!strcmp(line, "color"))
command = COLOR;
else if (!strcmp(line, "merdella"))
command = MERDELLA;
else
kprintf(0, "invalid command: %s\n", line);
if (uwu)
line[i] = ' ';
return command;
}
static void read_line(void)
{
size_t i = 0;
struct key_event ev;
uint8_t prev_scan_code = 0;
while (1) {
ev = terminal_getkey();
if (ev.c == '\n')
break;
char *buf = screen->line;
i = strlen(screen->line);
const size_t size = sizeof(screen->line);
if (prev_scan_code != ev.scan_code && ev.scan_code) {
if (ev.scan_code == KEY_BACKSPACE && i) {
buf[--i] = '\0';
move_cursor(LEFT);
terminal_putchar(' ');
move_cursor(LEFT);
}
if (ev.c && i < size - 1) {
kprintf(0, "%c", ev.c);
buf[i++] = ev.c;
}
if (i >= size)
break;
}
prev_scan_code = ev.scan_code;
}
kprintf(0, "\n");
screen->line[i] = '\0';
}
void shell_init(void)
{
while (1) {
kprintf(0, PROMPT);
read_line();
switch (find_command(screen->line)) {
case HELP:
kprintf(0, "Welcome to bozOShell, the shell of "
"bozOS\nAvailable commands: help, reboot, "
"poweroff, echo, color, merdella\n");
break;
case REBOOT:
kprintf(0, "rebooting\n");
break;
case POWEROFF:
kprintf(0, "powering off\n");
break;
case ECHO:
kprintf(0, "echoing\n");
break;
case COLOR:
kprintf(0, "coloring\n");
break;
case MERDELLA: {
kprintf(0, POOP);
if (!strcmp("merdella --credits", screen->line))
kprintf(
0,
"\nThis ascii masterpiece has been created "
"by Targon (/)\n");
break;
}
case ERROR:
break;
default:
break;
}
memset(screen->line, '\0', sizeof(screen->line));
}
}