diff --git a/.gitignore b/.gitignore index 8c03c21..ecbd5a1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ build/ .vscode/ +.vim/ *.log tags diff --git a/src/bytenuts.c b/src/bytenuts.c index 1382f3e..a77cd6f 100644 --- a/src/bytenuts.c +++ b/src/bytenuts.c @@ -29,6 +29,7 @@ static int parse_args(int argc, char **argv); static int load_configs(); +static int read_state(); static int load_state(); static speed_t string_to_speed(const char *speed); static const char *speed_to_string(speed_t speed); @@ -49,6 +50,10 @@ bytenuts_run(int argc, char **argv) return -1; } + if (bytenuts.resume) { + read_state(); + } + bytenuts.serial_fd = serial_open(bytenuts.config.serial_path, bytenuts.config.baud); if (bytenuts.serial_fd < 0) { return -1; @@ -109,6 +114,13 @@ bytenuts_run(int argc, char **argv) if (bytenuts.resume) { load_state(); + } else { + cheerios_insert( + "Welcome to Bytenuts\r\n" + "To quit press ctrl-b q\r\n" + "To see all commands, press ctrl-b h\r\n", + 82 + ); } pthread_mutex_lock(&bytenuts.lock); @@ -392,54 +404,70 @@ load_configs() } static int -load_state() +read_state() { struct stat st; char *buf; + char *cwd = getcwd(NULL, 0); char *home = getenv("HOME"); FILE *fd; - buf = calloc(1, snprintf(NULL, 0, "%s/.config/bytenuts/inbuf.log", home) + 1); - sprintf(buf, "%s/.config/bytenuts/inbuf.log", home); - fd = fopen(buf, "r"); - stat(buf, &st); - free(buf); - - if (fd) { - char **history = NULL; - int history_len = 0; + chdir(home); + fd = fopen(".config/bytenuts/inbuf.log", "r"); + stat(".config/bytenuts/inbuf.log", &st); + if (fd && st.st_size > 0) { buf = calloc(1, st.st_size + 1); while (fgets(buf, st.st_size+1, fd)) { - history_len++; - history = realloc(history, sizeof(char *) * history_len); - history[history_len-1] = strdup(buf); - } - fclose(fd); - - if (history) { - ingest_set_history(history); - for (int i = 0; i < history_len; i++) { - free(history[i]); - } - free(history); + bytenuts.state.history_len++; + bytenuts.state.history = realloc( + bytenuts.state.history, + sizeof(char *) * bytenuts.state.history_len + ); + bytenuts.state.history[bytenuts.state.history_len-1] = strdup(buf); } free(buf); } - - buf = calloc(1, snprintf(NULL, 0, "%s/.config/bytenuts/outbuf.log", home) + 1); - sprintf(buf, "%s/.config/bytenuts/outbuf.log", home); - fd = fopen(buf, "r"); - stat(buf, &st); - free(buf); - - if (fd) { - buf = malloc(st.st_size); - fread(buf, 1, st.st_size, fd); - cheerios_insert(buf, st.st_size); - free(buf); + if (fd) fclose(fd); + + stat(".config/bytenuts/outbuf.log", &st); + fd = fopen(".config/bytenuts/outbuf.log", "r"); + + if (fd && st.st_size > 0) { + bytenuts.state.buf = malloc(st.st_size); + bytenuts.state.buf_len = st.st_size; + fread(bytenuts.state.buf, 1, st.st_size, fd); + } + if (fd) + fclose(fd); + + chdir(cwd); + free(cwd); + + return 0; +} + +static int +load_state() +{ + if (bytenuts.state.history) { + ingest_set_history(bytenuts.state.history, bytenuts.state.history_len); + + for (int i = 0; i < bytenuts.state.history_len; i++) { + free(bytenuts.state.history[i]); + } + free(bytenuts.state.history); + bytenuts.state.history = NULL; + bytenuts.state.history_len = 0; + } + + if (bytenuts.state.buf) { + cheerios_insert(bytenuts.state.buf, bytenuts.state.buf_len); + free(bytenuts.state.buf); + bytenuts.state.buf = NULL; + bytenuts.state.buf_len = 0; } return 0; diff --git a/src/bytenuts.h b/src/bytenuts.h index 364e5b2..a8f470a 100644 --- a/src/bytenuts.h +++ b/src/bytenuts.h @@ -11,6 +11,13 @@ /* https://en.wikipedia.org/wiki/Control_character#How_control_characters_map_to_keyboards */ #define CTRL(c) ((c)&31) +typedef struct bytenuts_state_struct { + char **history; /* commands from previous session */ + int history_len; + char *buf; /* previous buffer */ + size_t buf_len; +} bytenuts_state_t; + typedef struct bytenuts_config_struct { int colors; /* enable terminal colors, default 1 */ int echo; /* echo user input to the output window, default 0 */ @@ -38,6 +45,7 @@ typedef struct bytenuts_struct { bytenuts_config_t config; int config_overrides[4]; int resume; + bytenuts_state_t state; WINDOW *status_win; WINDOW *out_win; WINDOW *in_win; diff --git a/src/cheerios.c b/src/cheerios.c index 557ebae..1527a6d 100644 --- a/src/cheerios.c +++ b/src/cheerios.c @@ -24,7 +24,7 @@ static int newline(line_buffer_t *lines); int cheerios_start(bytenuts_t *bytenuts) { - char *home; + char *home = getenv("HOME"); char *cwd; memset(&cheerios, 0, sizeof(cheerios_t)); diff --git a/src/ingest.c b/src/ingest.c index 7f1801b..3b48079 100644 --- a/src/ingest.c +++ b/src/ingest.c @@ -81,7 +81,7 @@ ingest_stop() } int -ingest_set_history(char **history) +ingest_set_history(char **history, int history_len) { if (ingest.history) { for (int i = 0; ingest.history[i] != NULL; i++) { @@ -90,16 +90,28 @@ ingest_set_history(char **history) free(ingest.history); } - ingest.history = calloc(1, sizeof(char *)); - for (int i = 0; history[i] != NULL; i++) { - ingest.history = realloc( - ingest.history, - (i+2) * sizeof(char *) - ); + ingest.history = calloc(1, sizeof(char *) * (history_len+1)); + for (int i = 0; i < history_len; i++) { + size_t item_len = strlen(history[i]); ingest.history[i] = strdup(history[i]); - ingest.history[i+1] = NULL; + + while ( + ingest.history[i][item_len-1] == '\n' || + ingest.history[i][item_len-1] == '\r' + ) { + item_len--; + ingest.history[i][item_len] = '\0'; + } + + if (ingest.history_fd) { + fwrite(ingest.history[i], 1, item_len, ingest.history_fd); + fwrite("\n", 1, 1, ingest.history_fd); + } } + ingest.history_len = history_len; + ingest.history_pos = ingest.history_len; + return 0; } @@ -112,12 +124,6 @@ ingest_thread(void *arg) memset(ingest.inbuf, 0, sizeof(ingest.inbuf)); ingest.inpos = 0; - cheerios_insert( - "Welcome to Bytenuts\r\n" - "To quit press ctrl-b q\r\n" - "To see all commands, press ctrl-b h\r\n", - 82 - ); bytenuts_set_status(STATUS_INGEST, "normal"); while (ingest.running) { diff --git a/src/ingest.h b/src/ingest.h index 66235ad..d069827 100644 --- a/src/ingest.h +++ b/src/ingest.h @@ -19,12 +19,12 @@ typedef struct ingest_struct { pthread_t thr; volatile int running; char *prepend; /* string to be prepended in the prompt */ - char inbuf[1024]; + char inbuf[4096]; int inpos; /* cursor position within the inbuf itself */ int inlen; /* length of the input buffer */ char **history; /* array of strings representing the command history */ FILE *history_fd; - char tmp_history[1024]; /* copy of inbuf before we load in history */ + char tmp_history[4096]; /* copy of inbuf before we load in history */ int history_len; int history_pos; /* where we currently reside in the history */ int mode; @@ -47,6 +47,6 @@ int ingest_start(bytenuts_t *bytenuts); int ingest_stop(); /* Set the the command history directly. Values are copied */ -int ingest_set_history(char **history); +int ingest_set_history(char **history, int history_len); #endif /* _INGEST_H_ */