diff --git a/headers/keyboard.h b/headers/keyboard.h index 3234270..2c8810f 100644 --- a/headers/keyboard.h +++ b/headers/keyboard.h @@ -2,7 +2,7 @@ #include -static const char *keymap[128] = { +[[__maybe_unused__]] static const char *keymap[128] = { [2] = "1!", [3] = "2@", [4] = "3#", [5] = "4$", [6] = "5%", [7] = "6^", [8] = "7&", [9] = "8*", [10] = "9(", [11] = "0)", [12] = "-_", [13] = "=+", [16] = "qQ", [17] = "wW", [18] = "eE", diff --git a/headers/shell.h b/headers/shell.h index 481b078..b122e62 100644 --- a/headers/shell.h +++ b/headers/shell.h @@ -2,7 +2,7 @@ #define PROMPT "> " -static const char *POOP = +[[__maybe_unused__]] static const char *POOP = " / ____/ / _ \\\n" " _/ ___/_ / / \\___ \\_\n" " / _/'-, `---._ / / \\_ \\\n" @@ -43,22 +43,9 @@ static const char *POOP = " \\_ \\___\"\"\"/\"\" / `\"\"/\"\" " "\n"; -typedef enum { - HELP, - REBOOT, - POWEROFF, - HALT, - STACK, - CLEAR, - ECHO, - COLOR, - MERDELLA, - DATE, - ERROR -} CMD_TOK; - void shell_init(void); void reboot(void); void halt(void); void print_stack(void); void date(void); +void merdella(void); diff --git a/headers/terminal.h b/headers/terminal.h index a08c7f3..8448baf 100644 --- a/headers/terminal.h +++ b/headers/terminal.h @@ -50,4 +50,3 @@ void terminal_clear(void); struct key_event terminal_getkey(void); void update_cursor(void); void move_cursor(int direction); -struct screen *get_screen(void); diff --git a/src/gdt/set_gdt.s b/src/gdt/set_gdt.s index 8783dda..eaf5902 100644 --- a/src/gdt/set_gdt.s +++ b/src/gdt/set_gdt.s @@ -15,4 +15,5 @@ mov ss, ax jmp 0x08:.flush // 0x08 is the offset to our code segment: far jump on it .flush: - ret \ No newline at end of file +ret + diff --git a/src/rtc/rtc.c b/src/rtc/rtc.c index ff0164b..26159c9 100644 --- a/src/rtc/rtc.c +++ b/src/rtc/rtc.c @@ -31,7 +31,7 @@ uint8_t bcd_mode_to_bin(uint8_t value) struct rtc_date get_date(void) { - struct rtc_date rv; + struct rtc_date rv = {}; uint8_t century; rv.second = read_register(SECOND_REGISTER); @@ -55,4 +55,4 @@ struct rtc_date get_date(void) } rv.year += century * 100 - 98; // -108 = bozo offset return rv; -} \ No newline at end of file +} diff --git a/src/shell/color.c b/src/shell/color.c deleted file mode 100644 index e69de29..0000000 diff --git a/src/shell/echo.c b/src/shell/echo.c deleted file mode 100644 index e69de29..0000000 diff --git a/src/shell/exec.c b/src/shell/exec.c index 9751424..7c74b89 100644 --- a/src/shell/exec.c +++ b/src/shell/exec.c @@ -3,49 +3,68 @@ #include "string.h" #include "terminal.h" +#define NB_CMDS 8 +#define BORDER "===========================================================" +#define HEADER "Welcome to bozOShell - Available Commands" + extern struct screen *screen; -static CMD_TOK find_command(char *line) -{ - size_t i = 0; - bool uwu = false; - CMD_TOK command = ERROR; +struct shell_command { + char name[16]; + char description[256]; + void (*fn)(void); +}; - if (!line[0]) - return command; - while (line[i]) { - if (line[i] == ' ') { - uwu = true; - break; - } - i++; +static void help(void); + +static const struct shell_command commands[NB_CMDS] = { + {"help", "Print this help menu", help}, + {"reboot", "Reboot the system", reboot}, + {"poweroff", "Shut down the system", halt}, + {"halt", "Stop all CPU functions", halt}, + {"stack", "Print the stack trace", print_stack}, + {"clear", "Clear the current terminal", terminal_clear}, + {"date", "Display the current time and date (UTC+0)", date}, + {"merdella", "Surprise", merdella}, +}; + +static void help(void) +{ + const size_t padding = 15; + + kprintf(0, "%s\n", BORDER); + kprintf(0, " %s\n", HEADER); + kprintf(0, "%s\n", BORDER); + + for (size_t i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) { + kprintf(0, " %s", commands[i].name); + for (size_t j = 0; j < (padding - strlen(commands[i].name)); + j++) + kprintf(0, " "); + kprintf(0, ": %s\n", commands[i].description); + } + + kprintf(0, "%s\n", BORDER); +} + +static void auto_complete(void) +{ + const size_t len = strlen(screen->line); + int nb_matches = 0; + const char *last_match; + + for (size_t i = 0; i < NB_CMDS; i++) { + if (!strncmp(screen->line, commands[i].name, len)) { + nb_matches++; + last_match = commands[i].name; + } + } + if (nb_matches != 1) + return; + for (size_t i = len; last_match[i]; i++) { + screen->line[i] = last_match[i]; + kprintf(0, "%c", screen->line[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, "halt")) - command = HALT; - else if (!strcmp(line, "stack")) - command = STACK; - else if (!strcmp(line, "clear")) - command = CLEAR; - else if (!strcmp(line, "echo")) - command = ECHO; - else if (!strcmp(line, "color")) - command = COLOR; - else if (!strcmp(line, "merdella")) - command = MERDELLA; - else if (!strcmp(line, "date")) - command = DATE; - else - kprintf(0, "invalid command: %s\n", line); - if (uwu) - line[i] = ' '; - return command; } static void read_line(void) @@ -67,8 +86,9 @@ static void read_line(void) move_cursor(LEFT); terminal_putchar(' '); move_cursor(LEFT); - } - if (ev.c && i < size - 1) { + } else if (ev.scan_code == KEY_TAB && i) { + auto_complete(); + } else if (ev.c && i < size - 1) { kprintf(0, "%c", ev.c); buf[i++] = ev.c; } @@ -86,50 +106,16 @@ 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: - reboot(); - break; - case POWEROFF: - kprintf(0, "powering off\n"); - break; - case HALT: - halt(); - break; - case STACK: - print_stack(); - break; - case CLEAR: - terminal_clear(); - 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 DATE: - date(); - break; - case ERROR: - break; - default: - break; + bool invalid = true; + for (int i = 0; i < NB_CMDS; i++) { + if (!strcmp(commands[i].name, screen->line)) { + commands[i].fn(); + invalid = false; + break; + } } + if (invalid && screen->line[0]) + kprintf(0, "invalid command: %s\n", screen->line); memset(screen->line, '\0', sizeof(screen->line)); } } diff --git a/src/shell/misc_cmds.c b/src/shell/misc_cmds.c new file mode 100644 index 0000000..6a3f8ad --- /dev/null +++ b/src/shell/misc_cmds.c @@ -0,0 +1,7 @@ +#include "kprintf.h" +#include "shell.h" + +void merdella(void) +{ + kprintf(0, POOP); +} diff --git a/src/terminal/put.c b/src/terminal/put.c index 81e31de..8e3bd73 100644 --- a/src/terminal/put.c +++ b/src/terminal/put.c @@ -183,8 +183,3 @@ void move_cursor(int direction) outb(0x3D4, 0x0E); outb(0x3D5, (pos >> 8) & 0xFF); } - -struct screen *get_screen(void) -{ - return screen; -}