:: commit 530b4a8f3be926a498043477eb020a03391aa2b6

mintsuki <mintsuki@protonmail.com> — 2020-10-27 07:09

parents: b8b7a798d4

readline: Initial implementation

diff --git a/limine.bin b/limine.bin
index 4293c505..559ba57d 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2/lib/blib.c b/stage2/lib/blib.c
index d2d2e1a6..1d89e5a5 100644
--- a/stage2/lib/blib.c
+++ b/stage2/lib/blib.c
@@ -206,71 +206,3 @@ int getchar(void) {
     rm_int(0x16, &r, &r);
     return getchar_internal(r.eax);
 }
-
-static void gets_reprint_string(int x, int y, const char *s, size_t limit) {
-    int last_x, last_y;
-    get_cursor_pos(&last_x, &last_y);
-    set_cursor_pos(x, y);
-    for (size_t i = 0; i < limit; i++) {
-        term_write(" ", 1);
-    }
-    set_cursor_pos(x, y);
-    term_write(s, strlen(s));
-    set_cursor_pos(last_x, last_y);
-}
-
-void gets(const char *orig_str, char *buf, size_t limit) {
-    size_t orig_str_len = strlen(orig_str);
-    memmove(buf, orig_str, orig_str_len);
-    buf[orig_str_len] = 0;
-
-    int orig_x, orig_y;
-    get_cursor_pos(&orig_x, &orig_y);
-
-    print("%s", buf);
-
-    for (size_t i = orig_str_len; ; ) {
-        int c = getchar();
-        switch (c) {
-            case GETCHAR_CURSOR_LEFT:
-                if (i) {
-                    i--;
-                    term_write("\b", 1);
-                }
-                continue;
-            case GETCHAR_CURSOR_RIGHT:
-                if (i < strlen(buf)) {
-                    i++;
-                    term_write(" ", 1);
-                    gets_reprint_string(orig_x, orig_y, buf, limit);
-                }
-                continue;
-            case '\b':
-                if (i) {
-                    i--;
-                    for (size_t j = i; ; j++) {
-                        buf[j] = buf[j+1];
-                        if (!buf[j])
-                            break;
-                    }
-                    term_write("\b", 1);
-                    gets_reprint_string(orig_x, orig_y, buf, limit);
-                }
-                continue;
-            case '\r':
-                term_write("\n", 1);
-                return;
-            default:
-                if (strlen(buf) < limit-1) {
-                    for (size_t j = strlen(buf); ; j--) {
-                        buf[j+1] = buf[j];
-                        if (j == i)
-                            break;
-                    }
-                    buf[i++] = c;
-                    term_write(" ", 1);
-                    gets_reprint_string(orig_x, orig_y, buf, limit);
-                }
-        }
-    }
-}
diff --git a/stage2/lib/blib.h b/stage2/lib/blib.h
index 8dc60a53..f36c2dc8 100644
--- a/stage2/lib/blib.h
+++ b/stage2/lib/blib.h
@@ -33,7 +33,6 @@ int pit_sleep_and_quit_on_keypress(uint32_t pit_ticks);
 #define GETCHAR_CURSOR_DOWN  (-13)
 
 int getchar(void);
-void gets(const char *orig_str, char *buf, size_t limit);
 uint64_t strtoui(const char *s);
 uint64_t strtoui16(const char *s);
 
diff --git a/stage2/lib/readline.c b/stage2/lib/readline.c
new file mode 100644
index 00000000..59bfa662
--- /dev/null
+++ b/stage2/lib/readline.c
@@ -0,0 +1,100 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <lib/readline.h>
+#include <lib/libc.h>
+#include <lib/blib.h>
+#include <lib/term.h>
+
+static void reprint_string(int x, int y, const char *s) {
+    int orig_x, orig_y;
+    disable_cursor();
+    get_cursor_pos(&orig_x, &orig_y);
+    set_cursor_pos(x, y);
+    term_write(s, strlen(s));
+    set_cursor_pos(orig_x, orig_y);
+    enable_cursor();
+}
+
+static void cursor_back(void) {
+    int x, y;
+    get_cursor_pos(&x, &y);
+    if (x) {
+        x--;
+    } else if (y) {
+        y--;
+        x = term_cols - 1;
+    }
+    set_cursor_pos(x, y);
+}
+
+static void cursor_fwd(void) {
+    int x, y;
+    get_cursor_pos(&x, &y);
+    if (x < term_cols - 1) {
+        x++;
+    } else if (y < term_rows - 1) {
+        y++;
+        x = 0;
+    }
+    set_cursor_pos(x, y);
+}
+
+void readline(const char *orig_str, char *buf, size_t limit) {
+    size_t orig_str_len = strlen(orig_str);
+    memmove(buf, orig_str, orig_str_len);
+    buf[orig_str_len] = 0;
+
+    int orig_x, orig_y;
+    get_cursor_pos(&orig_x, &orig_y);
+
+    term_write(orig_str, orig_str_len);
+
+    for (size_t i = orig_str_len; ; ) {
+        int c = getchar();
+        switch (c) {
+            case GETCHAR_CURSOR_LEFT:
+                if (i) {
+                    i--;
+                    cursor_back();
+                }
+                continue;
+            case GETCHAR_CURSOR_RIGHT:
+                if (i < strlen(buf)) {
+                    i++;
+                    cursor_fwd();
+                }
+                continue;
+            case '\b':
+                if (i) {
+                    i--;
+                    cursor_back();
+                    size_t j;
+                    for (j = i; ; j++) {
+                        buf[j] = buf[j+1];
+                        if (!buf[j]) {
+                            buf[j] = ' ';
+                            break;
+                        }
+                    }
+                    reprint_string(orig_x, orig_y, buf);
+                    buf[j] = 0;
+                }
+                continue;
+            case '\r':
+                term_write("\n", 1);
+                return;
+            default:
+                if (strlen(buf) < limit - 1) {
+                    for (size_t j = strlen(buf); ; j--) {
+                        buf[j+1] = buf[j];
+                        if (j == i)
+                            break;
+                    }
+                    buf[i] = c;
+                    i++;
+                    cursor_fwd();
+                    reprint_string(orig_x, orig_y, buf);
+                }
+        }
+    }
+}
diff --git a/stage2/lib/readline.h b/stage2/lib/readline.h
new file mode 100644
index 00000000..44061fa3
--- /dev/null
+++ b/stage2/lib/readline.h
@@ -0,0 +1,8 @@
+#ifndef __LIB__READLINE_H__
+#define __LIB__READLINE_H__
+
+#include <stddef.h>
+
+void readline(const char *orig_str, char *buf, size_t limit);
+
+#endif
diff --git a/stage2/lib/term.c b/stage2/lib/term.c
index 2eb660a4..17f2f8bf 100644
--- a/stage2/lib/term.c
+++ b/stage2/lib/term.c
@@ -22,11 +22,11 @@ void (*get_cursor_pos)(int *x, int *y);
 void (*set_text_fg)(int fg);
 void (*set_text_bg)(int bg);
 
-static int rows, cols;
+int term_rows, term_cols;
 
 void term_vbe(uint32_t *colours, int margin, int margin_gradient, struct image *background) {
     term_deinit();
-    vbe_tty_init(&rows, &cols, colours, margin, margin_gradient, background);
+    vbe_tty_init(&term_rows, &term_cols, colours, margin, margin_gradient, background);
 
     raw_putchar    = vbe_putchar;
     clear          = vbe_clear;
@@ -42,7 +42,7 @@ void term_vbe(uint32_t *colours, int margin, int margin_gradient, struct image *
 
 void term_textmode(void) {
     term_deinit();
-    init_vga_textmode(&rows, &cols);
+    init_vga_textmode(&term_rows, &term_cols);
 
     raw_putchar    = text_putchar;
     clear          = text_clear;
@@ -156,16 +156,16 @@ static void escape_parse(char c) {
         case 'B':
             if (esc_default0)
                 esc_value0 = 1;
-            if ((get_cursor_pos_y() + esc_value0) > (rows - 1))
-                esc_value0 = (rows - 1) - get_cursor_pos_y();
+            if ((get_cursor_pos_y() + esc_value0) > (term_rows - 1))
+                esc_value0 = (term_rows - 1) - get_cursor_pos_y();
             set_cursor_pos(get_cursor_pos_x(),
                                 get_cursor_pos_y() + esc_value0);
             break;
         case 'C':
             if (esc_default0)
                 esc_value0 = 1;
-            if ((get_cursor_pos_x() + esc_value0) > (cols - 1))
-                esc_value0 = (cols - 1) - get_cursor_pos_x();
+            if ((get_cursor_pos_x() + esc_value0) > (term_cols - 1))
+                esc_value0 = (term_cols - 1) - get_cursor_pos_x();
             set_cursor_pos(get_cursor_pos_x() + esc_value0,
                                 get_cursor_pos_y());
             break;
@@ -184,10 +184,10 @@ static void escape_parse(char c) {
                 esc_value0 = 0;
             if (esc_default1)
                 esc_value1 = 0;
-            if (esc_value1 >= cols)
-                esc_value1 = cols - 1;
-            if (esc_value0 >= rows)
-                esc_value0 = rows - 1;
+            if (esc_value1 >= term_cols)
+                esc_value1 = term_cols - 1;
+            if (esc_value0 >= term_rows)
+                esc_value0 = term_rows - 1;
             set_cursor_pos(esc_value1, esc_value0);
             break;
         case 'm':
@@ -208,7 +208,7 @@ static void escape_parse(char c) {
                     int x = get_cursor_pos_x();
                     int y = get_cursor_pos_y();
                     set_cursor_pos(0, y);
-                    for (int i = 0; i < cols; i++)
+                    for (int i = 0; i < term_cols; i++)
                         raw_putchar(' ');
                     set_cursor_pos(x, y);
                     break;
diff --git a/stage2/lib/term.h b/stage2/lib/term.h
index 9d7e967d..4bde2c32 100644
--- a/stage2/lib/term.h
+++ b/stage2/lib/term.h
@@ -19,4 +19,6 @@ void term_textmode(void);
 void term_deinit(void);
 void term_write(const char *buf, size_t count);
 
+extern int term_rows, term_cols;
+
 #endif
diff --git a/stage2/menu.c b/stage2/menu.c
index 180eea1f..1952f7d5 100644
--- a/stage2/menu.c
+++ b/stage2/menu.c
@@ -8,6 +8,7 @@
 #include <lib/libc.h>
 #include <lib/config.h>
 #include <lib/term.h>
+#include <lib/readline.h>
 #include <mm/pmm.h>
 #include <drivers/vbe.h>
 
@@ -193,7 +194,7 @@ timeout_aborted:
                     }
                 }
                 print("\n\n> ");
-                gets(cmdline, cmdline, CMDLINE_MAX);
+                readline(cmdline, cmdline, CMDLINE_MAX);
                 clear(true);
                 return cmdline;
         }
tab: 248 wrap: offon