Add the bstr history APIs
Trying out an opaque handle style
This commit is contained in:
parent
c274a55c0e
commit
0ecb1bab0c
2 changed files with 108 additions and 0 deletions
80
src/bstr.c
80
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
28
src/bstr.h
28
src/bstr.h
|
|
@ -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_ */
|
||||
|
|
|
|||
Loading…
Reference in a new issue