#include <readline/history.h>
#include "xmalloc.h"
#include <stdlib.h>
#define HISTSIZE 500
#define HISTORY_GROW_SIZE 50
static int history_max_entries = HISTSIZE;
static HIST_ENTRY **history = NULL;
static int history_size = 0;
static int history_length = 0;
static int history_offset;
static void init_hist_entry(HIST_ENTRY *hist_entry, const char *string)
{
hist_entry->line = xstrdup(string);
hist_entry->data = NULL;
}
static void destroy_hist_entry(HIST_ENTRY *hist_entry)
{
free(hist_entry->line);
}
static HIST_ENTRY *alloc_hist_entry(const char *string)
{
HIST_ENTRY *hist_entry;
hist_entry = xmalloc(sizeof (HIST_ENTRY));
init_hist_entry(hist_entry, string);
return hist_entry;
}
static void free_hist_entry(HIST_ENTRY *hist_entry)
{
destroy_hist_entry(hist_entry);
free(hist_entry);
}
void __attribute__ ((weak, visibility ("default"))) using_history()
{
history_offset = history_length;
}
void __attribute__ ((weak, visibility ("default"))) add_history(const char *string)
{
int i;
if (history_length == history_max_entries) {
if (history_length == 0)
return;
free_hist_entry(history[0]);
for (i = 0; i < history_length - 1; i++)
history[i] = history[i + 1];
}
else {
if (!history) {
history = xmalloc(HISTORY_GROW_SIZE * sizeof (HIST_ENTRY *));
history_size = HISTORY_GROW_SIZE;
}
else if (history_length == history_size - 1) {
history = xrealloc(history, (history_size + HISTORY_GROW_SIZE) * sizeof (HIST_ENTRY *));
history_size += HISTORY_GROW_SIZE;
}
history_length++;
}
history[history_length - 1] = alloc_hist_entry(string);
history[history_length] = NULL;
}
HIST_ENTRY __attribute__ ((weak, visibility ("default"))) **history_list()
{
return history;
}
int __attribute__ ((weak, visibility ("default"))) where_history()
{
return history_offset;
}
HIST_ENTRY __attribute__ ((weak, visibility ("default"))) *current_history()
{
return history ? history[history_offset] : NULL;
}
int __attribute__ ((weak, visibility ("default"))) history_set_pos(int pos)
{
if (pos < 0 || pos > history_length)
return 0;
history_offset = pos;
return 1;
}
HIST_ENTRY __attribute__ ((weak, visibility ("default"))) *previous_history()
{
if (history_offset == 0)
return NULL;
history_offset--;
return history[history_offset];
}
HIST_ENTRY __attribute__ ((weak, visibility ("default"))) *next_history()
{
if (history_offset == history_length)
return NULL;
history_offset++;
return history[history_offset];
}