diff --git a/Makefile b/Makefile index 7f72174..95ff32a 100644 --- a/Makefile +++ b/Makefile @@ -16,3 +16,4 @@ include make/libioutil.mk include make/libmath.mk include make/libfat.mk include make/libdebugconsole.mk +include make/libinput.mk diff --git a/aux/compiledb.sh b/aux/compiledb.sh index 16a1827..25e5781 100755 --- a/aux/compiledb.sh +++ b/aux/compiledb.sh @@ -15,4 +15,5 @@ make -B all_compiledb_libioutil make -B all_compiledb_libmath make -B all_compiledb_libfat make -B all_compiledb_libdebugconsole +make -B all_compiledb_libinput make -B compiledb_apps diff --git a/aux/devel.sh b/aux/devel.sh index f4dcf08..3b7ee21 100755 --- a/aux/devel.sh +++ b/aux/devel.sh @@ -22,6 +22,7 @@ make -B all_libioutil "$bt" make -B all_libmath "$bt" make -B all_libfat "$bt" make -B all_libdebugconsole "$bt" +make -B all_libinput "$bt" make -B all_apps "$bt" make -B all_dist ./aux/limine_iso_amd64.sh diff --git a/aux/docs.sh b/aux/docs.sh index b618fed..8d0d77b 100755 --- a/aux/docs.sh +++ b/aux/docs.sh @@ -16,5 +16,6 @@ make -B docs_libioutil make -B docs_libmath make -B docs_libfat make -B docs_libdebugconsole +make -B docs_libinput make -B docs_apps mkdocs build diff --git a/aux/format.sh b/aux/format.sh index 0a5dd5c..96934aa 100755 --- a/aux/format.sh +++ b/aux/format.sh @@ -15,4 +15,5 @@ make -B format_libioutil make -B format_libmath make -B format_libfat make -B format_libdebugconsole +make -B format_libinput make -B format_apps diff --git a/ce/Makefile b/ce/Makefile index 957c81b..2bfeba8 100644 --- a/ce/Makefile +++ b/ce/Makefile @@ -9,6 +9,7 @@ $(eval $(call add_lib,libterminal)) $(eval $(call add_lib,libfat)) $(eval $(call add_lib,libmalloc)) $(eval $(call add_lib,libdebugconsole)) +$(eval $(call add_lib,libinput)) $(eval $(call add_include,libkb)) cflags += -DPRINTF_INCLUDE_CONFIG_H=1 diff --git a/ce/ce.c b/ce/ce.c index 72bfe1d..9849c25 100644 --- a/ce/ce.c +++ b/ce/ce.c @@ -1,12 +1,11 @@ #include "arena_alloc.h" #include "context.h" -#include "gapbuffer.h" #include "interp.h" #include "strbuf.h" #include #include -#include -#include +#include +#include #include #include #include @@ -14,14 +13,10 @@ #include #include #include -#include #include #include -#include -#include -#define LINE_INIT_MAX 40 -#define PROMPT "$ " +#define PROMPT "$ " void* wmalloc (void* ctx, size_t size) { (void)ctx; @@ -51,7 +46,7 @@ void* warena_realloc (void* ctx, void* mem, size_t old, size_t new) { void warena_free (void* ctx, void* mem) { (void)ctx, (void)mem; } struct edit_line { - struct gapbuffer gb; + struct in_gb gb; size_t cursor; }; @@ -67,99 +62,14 @@ static void exec_line (const char* line) { void app_main (void) { libprocess_self_init (); - struct edit_line edit_line; - - const char* render = NULL; + char line[1024]; while (interp_is_running ()) { - gapbuffer_init (&warena_malloc, &arena, &edit_line.gb, LINE_INIT_MAX); - edit_line.cursor = 0; + memset (line, 0, sizeof (line)); - mprintf (PROMPT); + in_stream_read_line (PROMPT, line, sizeof (line) - 1); - for (;;) { - uint8_t ch; - - if (stream_read (process_get_pgid (), STREAM_IN, &ch, 1) <= 0) { - sched (); - continue; - } - - if (ch == '\n') - break; - - gapbuffer_move (&edit_line.gb, edit_line.cursor); - - switch (ch) { - case '\b': - if (edit_line.cursor > 0) { - edit_line.cursor--; - gapbuffer_backspace (&edit_line.gb); - - mprintf (ANSIQ_CUR_LEFT (1)); - - char* tail = - gapbuffer_string_at (&warena_malloc, &arena, &edit_line.gb, edit_line.cursor); - mprintf ("%s" ANSIQ_SCR_CLR2LEND, tail); - - int move_back = strlen (tail); - if (move_back > 0) - mprintf (ANSIQ_DYN_CUR_LEFT, move_back); - } - break; - case KB_DELETE: - if (edit_line.cursor < gapbuffer_length (&edit_line.gb)) { - edit_line.gb.gap_end++; - - char* tail = - gapbuffer_string_at (&warena_malloc, &arena, &edit_line.gb, edit_line.cursor); - mprintf ("%s" ANSIQ_SCR_CLR2LEND, tail); - - int move_back = strlen (tail); - if (move_back > 0) - mprintf (ANSIQ_DYN_CUR_LEFT, move_back); - } - break; - case KB_LEFT: - if (edit_line.cursor > 0) { - edit_line.cursor--; - mprintf (ANSIQ_CUR_LEFT (1)); - } - break; - case KB_RIGHT: - if (edit_line.cursor < gapbuffer_length (&edit_line.gb)) { - edit_line.cursor++; - mprintf (ANSIQ_CUR_RIGHT (1)); - } - break; - default: - if (isprint (ch)) { - gapbuffer_insert (&warena_realloc, &arena, &edit_line.gb, ch); - edit_line.cursor++; - - if (edit_line.cursor == gapbuffer_length (&edit_line.gb)) { - mprintf ("%c", ch); - } else { - char* tail = - gapbuffer_string_at (&warena_malloc, &arena, &edit_line.gb, edit_line.cursor - 1); - size_t move_back = strlen (tail) - 1; - mprintf ("%s" ANSIQ_DYN_CUR_LEFT, tail, move_back); - } - } - break; - } - } - - mprintf ("\n"); - - render = gapbuffer_string_at (&warena_malloc, &arena, &edit_line.gb, 0); - - if (render != NULL) - exec_line (render); - - gapbuffer_fini (&warena_free, &arena, &edit_line.gb); - arena_reset (&arena); + if (line[0] != '\0') + exec_line (line); } - - arena_destroy (&arena); } diff --git a/ce/edit.c b/ce/edit.c index 52326c9..955dc9e 100644 --- a/ce/edit.c +++ b/ce/edit.c @@ -1,9 +1,9 @@ #include "edit.h" #include "arena_alloc.h" -#include "gapbuffer.h" #include "walloc.h" #include #include +#include #include #include #include @@ -33,7 +33,7 @@ struct edit_line { struct list_node_link select_link; size_t select_start; size_t select_end; - struct gapbuffer gb; + struct in_gb gb; }; struct cursor { @@ -79,10 +79,10 @@ static bool prepare_lines_cb (void* ctx, const char* start, size_t len) { memset (line, 0, sizeof (*line)); size_t init_len = len > 0 ? len : 32; - gapbuffer_init (&wmalloc, NULL, &line->gb, init_len); + in_gb_init (&wmalloc, NULL, &line->gb, init_len); for (size_t chr = 0; chr < len; chr++) - gapbuffer_insert (&wrealloc, NULL, &line->gb, start[chr]); + in_gb_insert (&wrealloc, NULL, &line->gb, start[chr]); list_append (editor.lines, &line->lines_link); @@ -246,17 +246,17 @@ void edit_start (const char* volume, const char* file_path, const char* text, si case '\b': if (editor.mode == EDIT_MODE_NORMAL) { if (editor.cursor.col > 0) { - gapbuffer_move (&editor.current_line->gb, editor.cursor.col); + in_gb_move (&editor.current_line->gb, editor.cursor.col); editor.cursor.col--; - gapbuffer_backspace (&editor.current_line->gb); + in_gb_backspace (&editor.current_line->gb); } else { if (editor.cursor.line > 0) { struct list_node_link* prev = editor.current_line->lines_link.prev; struct edit_line* prev_line = list_entry (prev, struct edit_line, lines_link); - size_t prev_len = gapbuffer_length (&prev_line->gb); + size_t prev_len = in_gb_length (&prev_line->gb); - gapbuffer_concat (&wrealloc, NULL, &prev_line->gb, &editor.current_line->gb); + in_gb_concat (&wrealloc, NULL, &prev_line->gb, &editor.current_line->gb); list_remove (editor.lines, &editor.current_line->lines_link); free (editor.current_line->gb.buffer); @@ -272,26 +272,26 @@ void edit_start (const char* volume, const char* file_path, const char* text, si break; case '\t': if (editor.mode == EDIT_MODE_NORMAL) { - gapbuffer_move (&editor.current_line->gb, editor.cursor.col); + in_gb_move (&editor.current_line->gb, editor.cursor.col); for (size_t i = 0; i < sizeof (TAB_INSERT) - 1; i++) - gapbuffer_insert (&wrealloc, NULL, &editor.current_line->gb, TAB_INSERT[i]); + in_gb_insert (&wrealloc, NULL, &editor.current_line->gb, TAB_INSERT[i]); editor.cursor.col += sizeof (TAB_INSERT) - 1; } break; case '\n': { if (editor.mode == EDIT_MODE_NORMAL) { - gapbuffer_move (&editor.current_line->gb, editor.cursor.col); + in_gb_move (&editor.current_line->gb, editor.cursor.col); struct edit_line* new_line = malloc (sizeof (*new_line)); memset (new_line, 0, sizeof (*new_line)); - char* tail = gapbuffer_string_at (&warena_malloc, &temp_arena, &editor.current_line->gb, - editor.cursor.col); + char* tail = in_gb_string_at (&warena_malloc, &temp_arena, &editor.current_line->gb, + editor.cursor.col); size_t tail_size = strlen (tail); size_t init_cap = tail_size > 0 ? tail_size : 32; - gapbuffer_init (&wmalloc, NULL, &new_line->gb, init_cap); + in_gb_init (&wmalloc, NULL, &new_line->gb, init_cap); if (tail_size > 0) { memcpy (new_line->gb.buffer, @@ -337,10 +337,10 @@ void edit_start (const char* volume, const char* file_path, const char* text, si } break; case KB_DELETE: if (editor.mode == EDIT_MODE_NORMAL) { - size_t len = gapbuffer_length (&editor.current_line->gb); + size_t len = in_gb_length (&editor.current_line->gb); if (editor.cursor.col < len) { - gapbuffer_move (&editor.current_line->gb, editor.cursor.col); + in_gb_move (&editor.current_line->gb, editor.cursor.col); if (editor.current_line->gb.gap_end < editor.current_line->gb.size) editor.current_line->gb.gap_end++; } else { @@ -348,7 +348,7 @@ void edit_start (const char* volume, const char* file_path, const char* text, si struct list_node_link* next = editor.current_line->lines_link.next; struct edit_line* next_line = list_entry (next, struct edit_line, lines_link); - gapbuffer_concat (&wrealloc, NULL, &editor.current_line->gb, &next_line->gb); + in_gb_concat (&wrealloc, NULL, &editor.current_line->gb, &next_line->gb); list_remove (editor.lines, &next_line->lines_link); free (next_line->gb.buffer); @@ -362,7 +362,7 @@ void edit_start (const char* volume, const char* file_path, const char* text, si editor.cursor.col--; break; case KB_RIGHT: - if (editor.cursor.col < gapbuffer_length (&editor.current_line->gb)) + if (editor.cursor.col < in_gb_length (&editor.current_line->gb)) editor.cursor.col++; break; case KB_UP: { @@ -370,7 +370,7 @@ void edit_start (const char* volume, const char* file_path, const char* text, si editor.cursor.line--; editor.current_line = list_entry (editor.current_line->lines_link.prev, struct edit_line, lines_link); - size_t len = gapbuffer_length (&editor.current_line->gb); + size_t len = in_gb_length (&editor.current_line->gb); if (editor.cursor.col > len) editor.cursor.col = len; } @@ -380,7 +380,7 @@ void edit_start (const char* volume, const char* file_path, const char* text, si editor.cursor.line++; editor.current_line = list_entry (editor.current_line->lines_link.next, struct edit_line, lines_link); - size_t len = gapbuffer_length (&editor.current_line->gb); + size_t len = in_gb_length (&editor.current_line->gb); if (editor.cursor.col > len) editor.cursor.col = len; } @@ -389,7 +389,7 @@ void edit_start (const char* volume, const char* file_path, const char* text, si editor.cursor.col = 0; break; case KB_END: - editor.cursor.col = gapbuffer_length (&editor.current_line->gb); + editor.cursor.col = in_gb_length (&editor.current_line->gb); break; case KB_ESCAPE: if (editor.mode == EDIT_MODE_COMAMND) { @@ -411,8 +411,8 @@ void edit_start (const char* volume, const char* file_path, const char* text, si editor.cmdbuf.buffer[editor.cmdbuf.len] = '\0'; } } else if (editor.mode == EDIT_MODE_NORMAL) { - gapbuffer_move (&editor.current_line->gb, editor.cursor.col); - gapbuffer_insert (&wrealloc, NULL, &editor.current_line->gb, ch); + in_gb_move (&editor.current_line->gb, editor.cursor.col); + in_gb_insert (&wrealloc, NULL, &editor.current_line->gb, ch); editor.cursor.col++; } } diff --git a/ce/gapbuffer.h b/ce/gapbuffer.h deleted file mode 100644 index da94a23..0000000 --- a/ce/gapbuffer.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _GAPBUFFER_H -#define _GAPBUFFER_H - -#include -#include - -struct gapbuffer { - char* buffer; - size_t size; - size_t gap_start; - size_t gap_end; -}; - -typedef void* (*gb_malloc_func_t) (void*, size_t); - -typedef void* (*gb_realloc_func_t) (void*, void*, size_t, size_t); - -typedef void (*gb_free_func_t) (void*, void*); - -void gapbuffer_init (gb_malloc_func_t mallocfn, void* ctx, struct gapbuffer* gb, size_t capacity); - -void gapbuffer_fini (gb_free_func_t freefn, void* ctx, struct gapbuffer* gb); - -void gapbuffer_move (struct gapbuffer* gb, size_t pos); - -void gapbuffer_insert (gb_realloc_func_t reallocfn, void* ctx, struct gapbuffer* gb, char c); - -void gapbuffer_backspace (struct gapbuffer* gb); - -void gapbuffer_grow (gb_realloc_func_t reallocfn, void* ctx, struct gapbuffer* gb); - -size_t gapbuffer_length (struct gapbuffer* gb); - -char* gapbuffer_string_at (gb_malloc_func_t mallocfn, void* ctx, struct gapbuffer* gb, size_t pos); - -void gapbuffer_concat (gb_realloc_func_t reallocfn, void* ctx, struct gapbuffer* dest, - struct gapbuffer* src); - -#endif // _GAPBUFFER_H diff --git a/ce/interp.c b/ce/interp.c index c299555..85b874b 100644 --- a/ce/interp.c +++ b/ce/interp.c @@ -340,26 +340,15 @@ static void help (struct context* context) { cprintf (context, "quit\n"); } -static void cmd_cancel_proc (void* arg) { - int pid = (int)(uintptr_t)arg; - - uint8_t ch = 0; - for (;;) { - if (stream_read (process_get_pgid (), STREAM_IN, &ch, 1) > 0 && ch == KB_CTRL ('C')) - break; - else - sched (); - } - - kill (pid); -} +struct cmd_write_proc_ctx { + int pgid; + int cancel_pid; +}; static void cmd_collect_proc (void* arg) { -#define RECV_MAX (1024 * 16) - int pgid = (int)(uintptr_t)arg; - char recv[RECV_MAX]; + char recv[1024]; int n; for (;;) { if ((n = stream_read (pgid, STREAM_OUT, (void*)recv, sizeof (recv) - 1)) > 0) @@ -369,6 +358,24 @@ static void cmd_collect_proc (void* arg) { } } +static void cmd_write_proc (void* arg) { + struct cmd_write_proc_ctx* ctx = arg; + + uint8_t ch = 0; + for (;;) { + if (stream_read (process_get_pgid (), STREAM_IN, &ch, 1) > 0) { + if (ch == KB_CTRL ('C')) { + kill (ctx->cancel_pid); + return; + } + + stream_write (ctx->pgid, STREAM_IN, &ch, 1); + } else { + sched (); + } + } +} + static void execute_cmd (struct ast_cmd* cmd, struct context* context) { if (strcmp (cmd->name, "echo") == 0) { echo (context, cmd->args, cmd->arg_count); @@ -442,16 +449,18 @@ static void execute_cmd (struct ast_cmd* cmd, struct context* context) { } } + struct cmd_write_proc_ctx wpctx = {.pgid = pgid, .cancel_pid = pid}; + + struct process_data* write_pdata = process_spawn (&cmd_write_proc, (void*)&wpctx); struct process_data* collect_pdata = process_spawn (&cmd_collect_proc, (void*)(uintptr_t)pgid); - struct process_data* cancel_pdata = process_spawn (&cmd_cancel_proc, (void*)(uintptr_t)pid); exec_partial_fini (pid); wait_for_pid (pid); + kill (write_pdata->pid); + process_data_free (write_pdata); kill (collect_pdata->pid); process_data_free (collect_pdata); - kill (cancel_pdata->pid); - process_data_free (cancel_pdata); } } diff --git a/ce/src.mk b/ce/src.mk index 8c9bfaa..09c3e74 100644 --- a/ce/src.mk +++ b/ce/src.mk @@ -4,7 +4,6 @@ c += ce.c \ context.c \ parser.c \ interp.c \ - gapbuffer.c \ edit.c o += ce.o \ @@ -13,5 +12,4 @@ o += ce.o \ context.o \ parser.o \ interp.o \ - gapbuffer.o \ edit.o diff --git a/libinput/.gitignore b/libinput/.gitignore new file mode 100644 index 0000000..de276e3 --- /dev/null +++ b/libinput/.gitignore @@ -0,0 +1,4 @@ +*.o +*.json +docs/ +.cache/ diff --git a/libinput/Makefile b/libinput/Makefile new file mode 100644 index 0000000..15ffea8 --- /dev/null +++ b/libinput/Makefile @@ -0,0 +1,14 @@ +include ../make/ufuncs.mk + +$(eval $(call add_include,libsystem)) +$(eval $(call add_include,libstring)) +$(eval $(call add_include,libmalloc)) +$(eval $(call add_include,libaux)) +$(eval $(call add_include,libterminal)) +$(eval $(call add_include,libarena)) +$(eval $(call add_include,libkb)) +$(eval $(call add_include,libprocess)) + +libname := libinput + +include ../make/lib.mk diff --git a/libinput/build/.gitignore b/libinput/build/.gitignore new file mode 100644 index 0000000..10301e2 --- /dev/null +++ b/libinput/build/.gitignore @@ -0,0 +1 @@ +*.a diff --git a/ce/gapbuffer.c b/libinput/in_gb.c similarity index 68% rename from ce/gapbuffer.c rename to libinput/in_gb.c index 75a7332..163972b 100644 --- a/ce/gapbuffer.c +++ b/libinput/in_gb.c @@ -1,11 +1,9 @@ -#include "gapbuffer.h" -#include "arena_alloc.h" -#include +#include #include #include #include -void gapbuffer_init (gb_malloc_func_t mallocfn, void* ctx, struct gapbuffer* gb, size_t capacity) { +void in_gb_init (in_gb_malloc_func_t mallocfn, void* ctx, struct in_gb* gb, size_t capacity) { gb->buffer = mallocfn (ctx, capacity); if (gb->buffer == NULL) @@ -17,12 +15,12 @@ void gapbuffer_init (gb_malloc_func_t mallocfn, void* ctx, struct gapbuffer* gb, gb->gap_end = capacity; } -void gapbuffer_fini (gb_free_func_t freefn, void* ctx, struct gapbuffer* gb) { +void in_gb_fini (in_gb_free_func_t freefn, void* ctx, struct in_gb* gb) { freefn (ctx, gb->buffer); memset (gb, 0, sizeof (*gb)); } -void gapbuffer_grow (gb_realloc_func_t reallocfn, void* ctx, struct gapbuffer* gb) { +void in_gb_grow (in_gb_realloc_func_t reallocfn, void* ctx, struct in_gb* gb) { size_t old_size = gb->size; size_t new_size = gb->size * 2; @@ -42,7 +40,7 @@ void gapbuffer_grow (gb_realloc_func_t reallocfn, void* ctx, struct gapbuffer* g gb->size = new_size; } -void gapbuffer_move (struct gapbuffer* gb, size_t pos) { +void in_gb_move (struct in_gb* gb, size_t pos) { if (pos > (gb->size - (gb->gap_end - gb->gap_start))) pos = (gb->size - (gb->gap_end - gb->gap_start)); @@ -59,23 +57,23 @@ void gapbuffer_move (struct gapbuffer* gb, size_t pos) { } } -void gapbuffer_insert (gb_realloc_func_t reallocfn, void* ctx, struct gapbuffer* gb, char c) { +void in_gb_insert (in_gb_realloc_func_t reallocfn, void* ctx, struct in_gb* gb, char c) { if (gb->gap_start == gb->gap_end) - gapbuffer_grow (reallocfn, ctx, gb); + in_gb_grow (reallocfn, ctx, gb); gb->buffer[gb->gap_start] = c; gb->gap_start++; } -void gapbuffer_backspace (struct gapbuffer* gb) { +void in_gb_backspace (struct in_gb* gb) { if (gb->gap_start > 0) gb->gap_start--; } -size_t gapbuffer_length (struct gapbuffer* gb) { return gb->size - (gb->gap_end - gb->gap_start); } +size_t in_gb_length (struct in_gb* gb) { return gb->size - (gb->gap_end - gb->gap_start); } -char* gapbuffer_string_at (gb_malloc_func_t mallocfn, void* ctx, struct gapbuffer* gb, size_t pos) { - size_t total_size = gapbuffer_length (gb); +char* in_gb_string_at (in_gb_malloc_func_t mallocfn, void* ctx, struct in_gb* gb, size_t pos) { + size_t total_size = in_gb_length (gb); if (pos >= total_size) return ""; @@ -113,17 +111,17 @@ char* gapbuffer_string_at (gb_malloc_func_t mallocfn, void* ctx, struct gapbuffe return res; } -void gapbuffer_concat (gb_realloc_func_t reallocfn, void* ctx, struct gapbuffer* dest, - struct gapbuffer* src) { - size_t src_len = gapbuffer_length (src); +void in_gb_concat (in_gb_realloc_func_t reallocfn, void* ctx, struct in_gb* dest, + struct in_gb* src) { + size_t src_len = in_gb_length (src); if (src_len == 0) return; while ((dest->gap_end - dest->gap_start) < src_len) - gapbuffer_grow (reallocfn, ctx, dest); + in_gb_grow (reallocfn, ctx, dest); - gapbuffer_move (dest, gapbuffer_length (dest)); + in_gb_move (dest, in_gb_length (dest)); size_t part1_len = src->gap_start; memcpy (dest->buffer + dest->gap_start, src->buffer, part1_len); diff --git a/libinput/in_gb.h b/libinput/in_gb.h new file mode 100644 index 0000000..01a8b99 --- /dev/null +++ b/libinput/in_gb.h @@ -0,0 +1,38 @@ +#ifndef _LIBINPUT_INPUT_GAPBUFFER_H +#define _LIBINPUT_INPUT_GAPBUFFER_H + +#include + +struct in_gb { + char* buffer; + size_t size; + size_t gap_start; + size_t gap_end; +}; + +typedef void* (*in_gb_malloc_func_t) (void*, size_t); + +typedef void* (*in_gb_realloc_func_t) (void*, void*, size_t, size_t); + +typedef void (*in_gb_free_func_t) (void*, void*); + +void in_gb_init (in_gb_malloc_func_t mallocfn, void* ctx, struct in_gb* gb, size_t capacity); + +void in_gb_fini (in_gb_free_func_t freefn, void* ctx, struct in_gb* gb); + +void in_gb_move (struct in_gb* gb, size_t pos); + +void in_gb_insert (in_gb_realloc_func_t reallocfn, void* ctx, struct in_gb* gb, char c); + +void in_gb_backspace (struct in_gb* gb); + +void in_gb_grow (in_gb_realloc_func_t reallocfn, void* ctx, struct in_gb* gb); + +size_t in_gb_length (struct in_gb* gb); + +char* in_gb_string_at (in_gb_malloc_func_t mallocfn, void* ctx, struct in_gb* gb, size_t pos); + +void in_gb_concat (in_gb_realloc_func_t reallocfn, void* ctx, struct in_gb* dest, + struct in_gb* src); + +#endif // _LIBINPUT_INPUT_GAPBUFFER_H diff --git a/libinput/in_input.c b/libinput/in_input.c new file mode 100644 index 0000000..823f1ee --- /dev/null +++ b/libinput/in_input.c @@ -0,0 +1,125 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void* in_wmalloc (void* ctx, size_t size) { + (void)ctx; + return malloc (size); +} + +static void in_wfree (void* ctx, void* mem) { + (void)ctx; + free (mem); +} + +static void* in_wrealloc (void* ctx, void* mem, size_t old, size_t new) { + (void)ctx, (void)old; + return realloc (mem, new); +} + +struct edit_line { + struct in_gb gb; + size_t cursor; +}; + +void in_stream_read_line (const char* prompt, char* buffer, size_t max) { + struct edit_line edit_line; + memset (&edit_line, 0, sizeof (edit_line)); + const char* render = NULL; + + in_gb_init (&in_wmalloc, NULL, &edit_line.gb, max); + edit_line.cursor = 0; + + mprintf ("%s", prompt); + + for (;;) { + uint8_t ch; + + if (stream_read (process_get_pgid (), STREAM_IN, &ch, 1) <= 0) { + sched (); + continue; + } + + if (ch == '\n') + break; + + in_gb_move (&edit_line.gb, edit_line.cursor); + + switch (ch) { + case '\b': + if (edit_line.cursor > 0) { + edit_line.cursor--; + in_gb_backspace (&edit_line.gb); + + mprintf (ANSIQ_CUR_LEFT (1)); + + char* tail = in_gb_string_at (&in_wmalloc, NULL, &edit_line.gb, edit_line.cursor); + mprintf ("%s" ANSIQ_SCR_CLR2LEND, tail); + + int move_back = strlen (tail); + if (move_back > 0) + mprintf (ANSIQ_DYN_CUR_LEFT, move_back); + } + break; + case KB_DELETE: + if (edit_line.cursor < in_gb_length (&edit_line.gb)) { + edit_line.gb.gap_end++; + + char* tail = in_gb_string_at (&in_wmalloc, NULL, &edit_line.gb, edit_line.cursor); + mprintf ("%s" ANSIQ_SCR_CLR2LEND, tail); + + int move_back = strlen (tail); + if (move_back > 0) + mprintf (ANSIQ_DYN_CUR_LEFT, move_back); + } + break; + case KB_LEFT: + if (edit_line.cursor > 0) { + edit_line.cursor--; + mprintf (ANSIQ_CUR_LEFT (1)); + } + break; + case KB_RIGHT: + if (edit_line.cursor < in_gb_length (&edit_line.gb)) { + edit_line.cursor++; + mprintf (ANSIQ_CUR_RIGHT (1)); + } + break; + default: + if (isprint (ch)) { + in_gb_insert (&in_wrealloc, NULL, &edit_line.gb, ch); + edit_line.cursor++; + + if (edit_line.cursor == in_gb_length (&edit_line.gb)) { + mprintf ("%c", ch); + } else { + char* tail = in_gb_string_at (&in_wmalloc, NULL, &edit_line.gb, edit_line.cursor - 1); + size_t move_back = strlen (tail) - 1; + mprintf ("%s" ANSIQ_DYN_CUR_LEFT, tail, move_back); + } + } + break; + } + } + + mprintf ("\n"); + + render = in_gb_string_at (&in_wmalloc, NULL, &edit_line.gb, 0); + + if (render != NULL) { + size_t len_render = strlen (render); + memcpy (buffer, render, min (len_render, max)); + } + + in_gb_fini (&in_wfree, NULL, &edit_line.gb); +} diff --git a/libinput/in_input.h b/libinput/in_input.h new file mode 100644 index 0000000..8710e7f --- /dev/null +++ b/libinput/in_input.h @@ -0,0 +1,8 @@ +#ifndef _LIBINPUT_IN_INPUT_H +#define _LIBINPUT_IN_INPUT_H + +#include + +void in_stream_read_line (const char* prompt, char* buffer, size_t max); + +#endif // _LIBINPUT_IN_INPUT_H diff --git a/libinput/src.mk b/libinput/src.mk new file mode 100644 index 0000000..a78759a --- /dev/null +++ b/libinput/src.mk @@ -0,0 +1,5 @@ +c += in_gb.c \ + in_input.c + +o += in_gb.o \ + in_input.o diff --git a/make/libinput.mk b/make/libinput.mk new file mode 100644 index 0000000..640f7b4 --- /dev/null +++ b/make/libinput.mk @@ -0,0 +1,16 @@ +all_libinput: + make -C libinput platform=$(platform) all + +all_compiledb_libinput: + bear --output libinput/compile_commands.json -- make -C libinput platform=$(platform) all + +clean_libinput: + make -C libinput platform=$(platform) clean + +format_libinput: + make -C libinput platform=$(platform) format + +docs_libinput: + make -C libinput platform=$(platform) docs + +.PHONY: all_libinput clean_libinput format_libinput docs_libinput all_compiledb_libinput diff --git a/sdutil/Makefile b/sdutil/Makefile index 299a3e8..cef092c 100644 --- a/sdutil/Makefile +++ b/sdutil/Makefile @@ -5,6 +5,8 @@ $(eval $(call add_lib,libprocess)) $(eval $(call add_lib,libaux)) $(eval $(call add_lib,libmalloc)) $(eval $(call add_lib,libdebugconsole)) +$(eval $(call add_lib,libmalloc)) +$(eval $(call add_lib,libinput)) cflags += -DPRINTF_INCLUDE_CONFIG_H=1 diff --git a/sdutil/sdutil.c b/sdutil/sdutil.c index 399dcc0..49e61ec 100644 --- a/sdutil/sdutil.c +++ b/sdutil/sdutil.c @@ -1,17 +1,30 @@ +#include #include #include #include +#include #include #define COMMAND_MAX 32 +static void start_part_dos (void) { + char dev_name[64]; + + in_stream_read_line ("Device name: ", dev_name, sizeof (dev_name)); +} + void app_main (void) { libprocess_self_init (); char commandbuf[COMMAND_MAX]; commandbuf[0] = '\0'; - if (env_get (process_get_pgid (), "C", (void*)commandbuf, sizeof (commandbuf)) == ST_OK) { - mprintf ("C=%s\n", commandbuf); + if (env_get (process_get_pgid (), "C", (void*)commandbuf, sizeof (commandbuf)) != ST_OK) { + mprintf ("ERROR C=???. No command provided\n"); + return; + } + + if (strcmp (commandbuf, "part_dos") == 0) { + start_part_dos (); } }