From 0ecb1bab0cb4f2a7a5be5e306ff4f2f820ad3326 Mon Sep 17 00:00:00 2001 From: Aaron Coook Date: Mon, 13 May 2024 00:10:01 -0500 Subject: [PATCH] Add the bstr history APIs Trying out an opaque handle style --- src/bstr.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/bstr.h | 28 +++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/src/bstr.c b/src/bstr.c index 30a70eb..b508ad6 100644 --- a/src/bstr.c +++ b/src/bstr.c @@ -5,6 +5,12 @@ #include "bstr.h" +typedef struct bstr_history_struct { + char **strs; /* strings in our history, in reverse chronological order */ + int len; /* number of strings in the history */ + int pos; /* current position index in the history */ +} bstr_history_t; + char * bstr_print(char *base, const char *fmt, ...) { @@ -35,3 +41,77 @@ bstr_print(char *base, const char *fmt, ...) return base; } } + +bstr_history_handle +bstr_history_create(void) +{ + bstr_history_t *ret = calloc(1, sizeof(bstr_history_t)); + ret->pos = -1; + return ret; +} + +const char * +bstr_history_atpos(bstr_history_handle hist) +{ + if ((hist->len == 0) || (hist->pos < 0)) { + return NULL; + } else { + return hist->strs[hist->pos]; + } +} + +void +bstr_history_new_entry(bstr_history_handle hist, const char *str) +{ + /* stored in reverse chronological order */ + hist->len++; + hist->strs = realloc(hist->strs, sizeof(char *) * hist->len); + hist->strs[hist->len-1] = strdup(str); +} + +void +bstr_history_older(bstr_history_handle hist) +{ + if (hist->len == 0) + return; + + if (hist->pos == -1) { + hist->pos = hist->len - 1; + } else { + hist->pos--; + } + + if (hist->pos < 0) + hist->pos = 0; +} + +void +bstr_history_newer(bstr_history_handle hist) +{ + if ((hist->len == 0) || (hist->pos == -1)) + return; + + hist->pos++; + if (hist->pos >= hist->len) + hist->pos = -1; +} + +void +bstr_history_unset_pos(bstr_history_handle hist) +{ + hist->pos = -1; +} + +void +bstr_history_destroy(bstr_history_handle hist) +{ + if (!hist) + return; + + if (hist->len > 0) { + for (int i = 0; i < hist->len; i++) { + free(hist->strs[i]); + } + free(hist->strs); + } +} diff --git a/src/bstr.h b/src/bstr.h index c442da3..b87585f 100644 --- a/src/bstr.h +++ b/src/bstr.h @@ -4,9 +4,37 @@ #include #include +typedef struct bstr_history_struct * bstr_history_handle; + + /* printf onto the end of base, reallocating and returning that buffer * can provide NULL for no base */ __attribute__((format(printf, 2, 3))) char *bstr_print(char *base, const char *fmt, ...); +/* Create a new bstr_history struct. The position of the history will start as + * unset. */ +bstr_history_handle bstr_history_create(void); + +/* return the string at the current history position (NULL if empty or position + * is not set) */ +const char *bstr_history_atpos(bstr_history_handle hist); + +/* Put a new entry into the history */ +void bstr_history_new_entry(bstr_history_handle hist, const char *str); + +/* Move the postition index one entry older. If the history position is unset, + * it is set to the newest entry. */ +void bstr_history_older(bstr_history_handle hist); + +/* Move the position index one entry newer. If the position is at the newest + * entry, it becomes unset. If the position is unset, it stays unset. */ +void bstr_history_newer(bstr_history_handle hist); + +/* Unset the history position index */ +void bstr_history_unset_pos(bstr_history_handle hist); + +/* destroy/free a bstr_history */ +void bstr_history_destroy(bstr_history_handle hist); + #endif /* _BSTR_H_ */