Add the bstr history APIs

Trying out an opaque handle style
This commit is contained in:
Aaron Cook 2024-05-13 00:10:01 -05:00
commit 0ecb1bab0c
2 changed files with 108 additions and 0 deletions

View file

@ -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);
}
}

View file

@ -4,9 +4,37 @@
#include <stdarg.h>
#include <stdio.h>
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_ */