Updated libedit to NetBSD upstream

Note: This unconditionally assumes wchar_t support.  May need revision
if some platforms prove problematic.
This commit is contained in:
Viktor Dukhovni
2016-11-13 15:49:16 +11:00
parent e1c1cdb1b6
commit 77ff7185d7
55 changed files with 6113 additions and 4536 deletions

View File

@@ -1,4 +1,4 @@
/* $NetBSD: history.c,v 1.38 2011/01/16 03:05:51 christos Exp $ */
/* $NetBSD: history.c,v 1.57 2016/04/11 18:56:31 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -32,39 +32,72 @@
* SUCH DAMAGE.
*/
#ifndef NARROWCHAR
#include "config.h"
#endif
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: history.c,v 1.38 2011/01/16 03:05:51 christos Exp $");
__RCSID("$NetBSD: history.c,v 1.57 2016/04/11 18:56:31 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
/*
* hist.c: TYPE(History) access functions
*/
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <vis.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <vis.h>
static const char hist_cookie[] = "_HiStOrY_V2_\n";
#include "histedit.h"
#ifdef NARROWCHAR
#define Char char
#define FUN(prefix, rest) prefix ## _ ## rest
#define FUNW(type) type
#define TYPE(type) type
#define STR(x) x
#define Strlen(s) strlen(s)
#define Strdup(s) strdup(s)
#define Strcmp(d, s) strcmp(d, s)
#define Strncmp(d, s, n) strncmp(d, s, n)
#define Strncpy(d, s, n) strncpy(d, s, n)
#define Strncat(d, s, n) strncat(d, s, n)
#define ct_decode_string(s, b) (s)
#define ct_encode_string(s, b) (s)
#else
#include "chartype.h"
typedef int (*history_gfun_t)(ptr_t, TYPE(HistEvent) *);
typedef int (*history_efun_t)(ptr_t, TYPE(HistEvent) *, const Char *);
typedef void (*history_vfun_t)(ptr_t, TYPE(HistEvent) *);
typedef int (*history_sfun_t)(ptr_t, TYPE(HistEvent) *, const int);
#define Char wchar_t
#define FUN(prefix, rest) prefix ## _w ## rest
#define FUNW(type) type ## _w
#define TYPE(type) type ## W
#define STR(x) L ## x
#define Strlen(s) wcslen(s)
#define Strdup(s) wcsdup(s)
#define Strcmp(d, s) wcscmp(d, s)
#define Strncmp(d, s, n) wcsncmp(d, s, n)
#define Strncpy(d, s, n) wcsncpy(d, s, n)
#define Strncat(d, s, n) wcsncat(d, s, n)
#endif
typedef int (*history_gfun_t)(void *, TYPE(HistEvent) *);
typedef int (*history_efun_t)(void *, TYPE(HistEvent) *, const Char *);
typedef void (*history_vfun_t)(void *, TYPE(HistEvent) *);
typedef int (*history_sfun_t)(void *, TYPE(HistEvent) *, const int);
struct TYPE(history) {
ptr_t h_ref; /* Argument for history fcns */
void *h_ref; /* Argument for history fcns */
int h_ent; /* Last entry point for history */
history_gfun_t h_first; /* Get the first element */
history_gfun_t h_next; /* Get the next element */
@@ -100,18 +133,20 @@ typedef struct {
} HistEventPrivate;
private int history_setsize(TYPE(History) *, TYPE(HistEvent) *, int);
private int history_getsize(TYPE(History) *, TYPE(HistEvent) *);
private int history_setunique(TYPE(History) *, TYPE(HistEvent) *, int);
private int history_getunique(TYPE(History) *, TYPE(HistEvent) *);
private int history_set_fun(TYPE(History) *, TYPE(History) *);
private int history_load(TYPE(History) *, const char *);
private int history_save(TYPE(History) *, const char *);
private int history_prev_event(TYPE(History) *, TYPE(HistEvent) *, int);
private int history_next_event(TYPE(History) *, TYPE(HistEvent) *, int);
private int history_next_string(TYPE(History) *, TYPE(HistEvent) *, const Char *);
private int history_prev_string(TYPE(History) *, TYPE(HistEvent) *, const Char *);
static int history_setsize(TYPE(History) *, TYPE(HistEvent) *, int);
static int history_getsize(TYPE(History) *, TYPE(HistEvent) *);
static int history_setunique(TYPE(History) *, TYPE(HistEvent) *, int);
static int history_getunique(TYPE(History) *, TYPE(HistEvent) *);
static int history_set_fun(TYPE(History) *, TYPE(History) *);
static int history_load(TYPE(History) *, const char *);
static int history_save(TYPE(History) *, const char *);
static int history_save_fp(TYPE(History) *, FILE *);
static int history_prev_event(TYPE(History) *, TYPE(HistEvent) *, int);
static int history_next_event(TYPE(History) *, TYPE(HistEvent) *, int);
static int history_next_string(TYPE(History) *, TYPE(HistEvent) *,
const Char *);
static int history_prev_string(TYPE(History) *, TYPE(HistEvent) *,
const Char *);
/***********************************************************************/
@@ -136,23 +171,23 @@ typedef struct history_t {
#define H_UNIQUE 1 /* Store only unique elements */
} history_t;
private int history_def_next(ptr_t, TYPE(HistEvent) *);
private int history_def_first(ptr_t, TYPE(HistEvent) *);
private int history_def_prev(ptr_t, TYPE(HistEvent) *);
private int history_def_last(ptr_t, TYPE(HistEvent) *);
private int history_def_curr(ptr_t, TYPE(HistEvent) *);
private int history_def_set(ptr_t, TYPE(HistEvent) *, const int);
private void history_def_clear(ptr_t, TYPE(HistEvent) *);
private int history_def_enter(ptr_t, TYPE(HistEvent) *, const Char *);
private int history_def_add(ptr_t, TYPE(HistEvent) *, const Char *);
private int history_def_del(ptr_t, TYPE(HistEvent) *, const int);
static int history_def_next(void *, TYPE(HistEvent) *);
static int history_def_first(void *, TYPE(HistEvent) *);
static int history_def_prev(void *, TYPE(HistEvent) *);
static int history_def_last(void *, TYPE(HistEvent) *);
static int history_def_curr(void *, TYPE(HistEvent) *);
static int history_def_set(void *, TYPE(HistEvent) *, const int);
static void history_def_clear(void *, TYPE(HistEvent) *);
static int history_def_enter(void *, TYPE(HistEvent) *, const Char *);
static int history_def_add(void *, TYPE(HistEvent) *, const Char *);
static int history_def_del(void *, TYPE(HistEvent) *, const int);
private int history_def_init(ptr_t *, TYPE(HistEvent) *, int);
private int history_def_insert(history_t *, TYPE(HistEvent) *, const Char *);
private void history_def_delete(history_t *, TYPE(HistEvent) *, hentry_t *);
static int history_def_init(void **, TYPE(HistEvent) *, int);
static int history_def_insert(history_t *, TYPE(HistEvent) *, const Char *);
static void history_def_delete(history_t *, TYPE(HistEvent) *, hentry_t *);
private int history_deldata_nth(history_t *, TYPE(HistEvent) *, int, void **);
private int history_set_nth(ptr_t, TYPE(HistEvent) *, int);
static int history_deldata_nth(history_t *, TYPE(HistEvent) *, int, void **);
static int history_set_nth(void *, TYPE(HistEvent) *, int);
#define history_def_setsize(p, num)(void) (((history_t *)p)->max = (num))
#define history_def_getsize(p) (((history_t *)p)->cur)
@@ -209,8 +244,8 @@ static const Char *const he_errlist[] = {
/* history_def_first():
* Default function to return the first event in the history.
*/
private int
history_def_first(ptr_t p, TYPE(HistEvent) *ev)
static int
history_def_first(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@@ -219,18 +254,18 @@ history_def_first(ptr_t p, TYPE(HistEvent) *ev)
*ev = h->cursor->ev;
else {
he_seterrev(ev, _HE_FIRST_NOTFOUND);
return (-1);
return -1;
}
return (0);
return 0;
}
/* history_def_last():
* Default function to return the last event in the history.
*/
private int
history_def_last(ptr_t p, TYPE(HistEvent) *ev)
static int
history_def_last(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@@ -239,69 +274,69 @@ history_def_last(ptr_t p, TYPE(HistEvent) *ev)
*ev = h->cursor->ev;
else {
he_seterrev(ev, _HE_LAST_NOTFOUND);
return (-1);
return -1;
}
return (0);
return 0;
}
/* history_def_next():
* Default function to return the next event in the history.
*/
private int
history_def_next(ptr_t p, TYPE(HistEvent) *ev)
static int
history_def_next(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
if (h->cursor == &h->list) {
he_seterrev(ev, _HE_EMPTY_LIST);
return (-1);
return -1;
}
if (h->cursor->next == &h->list) {
he_seterrev(ev, _HE_END_REACHED);
return (-1);
return -1;
}
h->cursor = h->cursor->next;
*ev = h->cursor->ev;
return (0);
return 0;
}
/* history_def_prev():
* Default function to return the previous event in the history.
*/
private int
history_def_prev(ptr_t p, TYPE(HistEvent) *ev)
static int
history_def_prev(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
if (h->cursor == &h->list) {
he_seterrev(ev,
(h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST);
return (-1);
return -1;
}
if (h->cursor->prev == &h->list) {
he_seterrev(ev, _HE_START_REACHED);
return (-1);
return -1;
}
h->cursor = h->cursor->prev;
*ev = h->cursor->ev;
return (0);
return 0;
}
/* history_def_curr():
* Default function to return the current event in the history.
*/
private int
history_def_curr(ptr_t p, TYPE(HistEvent) *ev)
static int
history_def_curr(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@@ -310,10 +345,10 @@ history_def_curr(ptr_t p, TYPE(HistEvent) *ev)
else {
he_seterrev(ev,
(h->cur > 0) ? _HE_CURR_INVALID : _HE_EMPTY_LIST);
return (-1);
return -1;
}
return (0);
return 0;
}
@@ -321,14 +356,14 @@ history_def_curr(ptr_t p, TYPE(HistEvent) *ev)
* Default function to set the current event in the history to the
* given one.
*/
private int
history_def_set(ptr_t p, TYPE(HistEvent) *ev, const int n)
static int
history_def_set(void *p, TYPE(HistEvent) *ev, const int n)
{
history_t *h = (history_t *) p;
if (h->cur == 0) {
he_seterrev(ev, _HE_EMPTY_LIST);
return (-1);
return -1;
}
if (h->cursor == &h->list || h->cursor->ev.num != n) {
for (h->cursor = h->list.next; h->cursor != &h->list;
@@ -338,9 +373,9 @@ history_def_set(ptr_t p, TYPE(HistEvent) *ev, const int n)
}
if (h->cursor == &h->list) {
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
return -1;
}
return (0);
return 0;
}
@@ -348,14 +383,14 @@ history_def_set(ptr_t p, TYPE(HistEvent) *ev, const int n)
* Default function to set the current event in the history to the
* n-th one.
*/
private int
history_set_nth(ptr_t p, TYPE(HistEvent) *ev, int n)
static int
history_set_nth(void *p, TYPE(HistEvent) *ev, int n)
{
history_t *h = (history_t *) p;
if (h->cur == 0) {
he_seterrev(ev, _HE_EMPTY_LIST);
return (-1);
return -1;
}
for (h->cursor = h->list.prev; h->cursor != &h->list;
h->cursor = h->cursor->prev)
@@ -363,17 +398,17 @@ history_set_nth(ptr_t p, TYPE(HistEvent) *ev, int n)
break;
if (h->cursor == &h->list) {
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
return -1;
}
return (0);
return 0;
}
/* history_def_add():
* Append string to element
*/
private int
history_def_add(ptr_t p, TYPE(HistEvent) *ev, const Char *str)
static int
history_def_add(void *p, TYPE(HistEvent) *ev, const Char *str)
{
history_t *h = (history_t *) p;
size_t len;
@@ -381,38 +416,38 @@ history_def_add(ptr_t p, TYPE(HistEvent) *ev, const Char *str)
HistEventPrivate *evp = (void *)&h->cursor->ev;
if (h->cursor == &h->list)
return (history_def_enter(p, ev, str));
return history_def_enter(p, ev, str);
len = Strlen(evp->str) + Strlen(str) + 1;
s = h_malloc(len * sizeof(*s));
if (s == NULL) {
he_seterrev(ev, _HE_MALLOC_FAILED);
return (-1);
return -1;
}
(void) Strncpy(s, h->cursor->ev.str, len);
s[len - 1] = '\0';
(void) Strncat(s, str, len - Strlen(s) - 1);
h_free((ptr_t)evp->str);
h_free(evp->str);
evp->str = s;
*ev = h->cursor->ev;
return (0);
return 0;
}
private int
static int
history_deldata_nth(history_t *h, TYPE(HistEvent) *ev,
int num, void **data)
{
if (history_set_nth(h, ev, num) != 0)
return (-1);
return -1;
/* magic value to skip delete (just set to n-th history) */
if (data == (void **)-1)
return (0);
return 0;
ev->str = Strdup(h->cursor->ev.str);
ev->num = h->cursor->ev.num;
if (data)
*data = h->cursor->data;
history_def_delete(h, ev, h->cursor);
return (0);
return 0;
}
@@ -420,17 +455,17 @@ history_deldata_nth(history_t *h, TYPE(HistEvent) *ev,
* Delete element hp of the h list
*/
/* ARGSUSED */
private int
history_def_del(ptr_t p, TYPE(HistEvent) *ev __attribute__((__unused__)),
static int
history_def_del(void *p, TYPE(HistEvent) *ev __attribute__((__unused__)),
const int num)
{
history_t *h = (history_t *) p;
if (history_def_set(h, ev, num) != 0)
return (-1);
return -1;
ev->str = Strdup(h->cursor->ev.str);
ev->num = h->cursor->ev.num;
history_def_delete(h, ev, h->cursor);
return (0);
return 0;
}
@@ -438,7 +473,7 @@ history_def_del(ptr_t p, TYPE(HistEvent) *ev __attribute__((__unused__)),
* Delete element hp of the h list
*/
/* ARGSUSED */
private void
static void
history_def_delete(history_t *h,
TYPE(HistEvent) *ev __attribute__((__unused__)), hentry_t *hp)
{
@@ -452,7 +487,7 @@ history_def_delete(history_t *h,
}
hp->prev->next = hp->next;
hp->next->prev = hp->prev;
h_free((ptr_t) evp->str);
h_free(evp->str);
h_free(hp);
h->cur--;
}
@@ -461,47 +496,49 @@ history_def_delete(history_t *h,
/* history_def_insert():
* Insert element with string str in the h list
*/
private int
static int
history_def_insert(history_t *h, TYPE(HistEvent) *ev, const Char *str)
{
hentry_t *c;
h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t));
if (h->cursor == NULL)
c = h_malloc(sizeof(*c));
if (c == NULL)
goto oomem;
if ((h->cursor->ev.str = h_strdup(str)) == NULL) {
h_free((ptr_t)h->cursor);
if ((c->ev.str = h_strdup(str)) == NULL) {
h_free(c);
goto oomem;
}
h->cursor->data = NULL;
h->cursor->ev.num = ++h->eventid;
h->cursor->next = h->list.next;
h->cursor->prev = &h->list;
h->list.next->prev = h->cursor;
h->list.next = h->cursor;
c->data = NULL;
c->ev.num = ++h->eventid;
c->next = h->list.next;
c->prev = &h->list;
h->list.next->prev = c;
h->list.next = c;
h->cur++;
h->cursor = c;
*ev = h->cursor->ev;
return (0);
*ev = c->ev;
return 0;
oomem:
he_seterrev(ev, _HE_MALLOC_FAILED);
return (-1);
return -1;
}
/* history_def_enter():
* Default function to enter an item in the history
*/
private int
history_def_enter(ptr_t p, TYPE(HistEvent) *ev, const Char *str)
static int
history_def_enter(void *p, TYPE(HistEvent) *ev, const Char *str)
{
history_t *h = (history_t *) p;
if ((h->flags & H_UNIQUE) != 0 && h->list.next != &h->list &&
Strcmp(h->list.next->ev.str, str) == 0)
return (0);
return 0;
if (history_def_insert(h, ev, str) == -1)
return (-1); /* error, keep error message */
return -1; /* error, keep error message */
/*
* Always keep at least one entry.
@@ -510,7 +547,7 @@ history_def_enter(ptr_t p, TYPE(HistEvent) *ev, const Char *str)
while (h->cur > h->max && h->cur > 0)
history_def_delete(h, ev, h->list.prev);
return (1);
return 1;
}
@@ -518,10 +555,10 @@ history_def_enter(ptr_t p, TYPE(HistEvent) *ev, const Char *str)
* Default history initialization function
*/
/* ARGSUSED */
private int
history_def_init(ptr_t *p, TYPE(HistEvent) *ev __attribute__((__unused__)), int n)
static int
history_def_init(void **p, TYPE(HistEvent) *ev __attribute__((__unused__)), int n)
{
history_t *h = (history_t *) h_malloc(sizeof(history_t));
history_t *h = (history_t *) h_malloc(sizeof(*h));
if (h == NULL)
return -1;
@@ -535,7 +572,7 @@ history_def_init(ptr_t *p, TYPE(HistEvent) *ev __attribute__((__unused__)), int
h->list.ev.num = 0;
h->cursor = &h->list;
h->flags = 0;
*p = (ptr_t) h;
*p = h;
return 0;
}
@@ -543,13 +580,14 @@ history_def_init(ptr_t *p, TYPE(HistEvent) *ev __attribute__((__unused__)), int
/* history_def_clear():
* Default history cleanup function
*/
private void
history_def_clear(ptr_t p, TYPE(HistEvent) *ev)
static void
history_def_clear(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
while (h->list.prev != &h->list)
history_def_delete(h, ev, h->list.prev);
h->cursor = &h->list;
h->eventid = 0;
h->cur = 0;
}
@@ -562,16 +600,16 @@ history_def_clear(ptr_t p, TYPE(HistEvent) *ev)
/* history_init():
* Initialization function.
*/
public TYPE(History) *
TYPE(History) *
FUN(history,init)(void)
{
TYPE(HistEvent) ev;
TYPE(History) *h = (TYPE(History) *) h_malloc(sizeof(TYPE(History)));
TYPE(History) *h = (TYPE(History) *) h_malloc(sizeof(*h));
if (h == NULL)
return NULL;
if (history_def_init(&h->h_ref, &ev, 0) == -1) {
h_free((ptr_t)h);
h_free(h);
return NULL;
}
h->h_ent = -1;
@@ -586,14 +624,14 @@ FUN(history,init)(void)
h->h_add = history_def_add;
h->h_del = history_def_del;
return (h);
return h;
}
/* history_end():
* clean up history;
*/
public void
void
FUN(history,end)(TYPE(History) *h)
{
TYPE(HistEvent) ev;
@@ -609,77 +647,77 @@ FUN(history,end)(TYPE(History) *h)
/* history_setsize():
* Set history number of events
*/
private int
static int
history_setsize(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return (-1);
return -1;
}
if (num < 0) {
he_seterrev(ev, _HE_BAD_PARAM);
return (-1);
return -1;
}
history_def_setsize(h->h_ref, num);
return (0);
return 0;
}
/* history_getsize():
* Get number of events currently in history
*/
private int
static int
history_getsize(TYPE(History) *h, TYPE(HistEvent) *ev)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return (-1);
return -1;
}
ev->num = history_def_getsize(h->h_ref);
if (ev->num < -1) {
he_seterrev(ev, _HE_SIZE_NEGATIVE);
return (-1);
return -1;
}
return (0);
return 0;
}
/* history_setunique():
* Set if adjacent equal events should not be entered in history.
*/
private int
static int
history_setunique(TYPE(History) *h, TYPE(HistEvent) *ev, int uni)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return (-1);
return -1;
}
history_def_setunique(h->h_ref, uni);
return (0);
return 0;
}
/* history_getunique():
* Get if adjacent equal events should not be entered in history.
*/
private int
static int
history_getunique(TYPE(History) *h, TYPE(HistEvent) *ev)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return (-1);
return -1;
}
ev->num = history_def_getunique(h->h_ref);
return (0);
return 0;
}
/* history_set_fun():
* Set history functions
*/
private int
static int
history_set_fun(TYPE(History) *h, TYPE(History) *nh)
{
TYPE(HistEvent) ev;
@@ -689,7 +727,8 @@ history_set_fun(TYPE(History) *h, TYPE(History) *nh)
nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL ||
nh->h_del == NULL || nh->h_ref == NULL) {
if (h->h_next != history_def_next) {
history_def_init(&h->h_ref, &ev, 0);
if (history_def_init(&h->h_ref, &ev, 0) == -1)
return -1;
h->h_first = history_def_first;
h->h_next = history_def_next;
h->h_last = history_def_last;
@@ -701,7 +740,7 @@ history_set_fun(TYPE(History) *h, TYPE(History) *nh)
h->h_add = history_def_add;
h->h_del = history_def_del;
}
return (-1);
return -1;
}
if (h->h_next == history_def_next)
history_def_clear(h->h_ref, &ev);
@@ -718,50 +757,49 @@ history_set_fun(TYPE(History) *h, TYPE(History) *nh)
h->h_add = nh->h_add;
h->h_del = nh->h_del;
return (0);
return 0;
}
/* history_load():
* TYPE(History) load function
*/
private int
static int
history_load(TYPE(History) *h, const char *fname)
{
FILE *fp;
char *line;
size_t sz, max_size;
size_t llen;
ssize_t sz;
size_t max_size;
char *ptr;
int i = -1;
TYPE(HistEvent) ev;
#ifdef WIDECHAR
#ifndef NARROWCHAR
static ct_buffer_t conv;
#endif
if ((fp = fopen(fname, "r")) == NULL)
return (i);
return i;
if ((line = fgetln(fp, &sz)) == NULL)
line = NULL;
llen = 0;
if ((sz = getline(&line, &llen, fp)) == -1)
goto done;
if (strncmp(line, hist_cookie, sz) != 0)
if (strncmp(line, hist_cookie, (size_t)sz) != 0)
goto done;
ptr = h_malloc(max_size = 1024);
ptr = h_malloc((max_size = 1024) * sizeof(*ptr));
if (ptr == NULL)
goto done;
for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) {
char c = line[sz];
if (sz != 0 && line[sz - 1] == '\n')
for (i = 0; (sz = getline(&line, &llen, fp)) != -1; i++) {
if (sz > 0 && line[sz - 1] == '\n')
line[--sz] = '\0';
else
line[sz] = '\0';
if (max_size < sz) {
if (max_size < (size_t)sz) {
char *nptr;
max_size = (sz + 1024) & ~1023;
nptr = h_realloc(ptr, max_size);
max_size = ((size_t)sz + 1024) & (size_t)~1023;
nptr = h_realloc(ptr, max_size * sizeof(*ptr));
if (nptr == NULL) {
i = -1;
goto oomem;
@@ -769,88 +807,104 @@ history_load(TYPE(History) *h, const char *fname)
ptr = nptr;
}
(void) strunvis(ptr, line);
line[sz] = c;
if (HENTER(h, &ev, ct_decode_string(ptr, &conv)) == -1) {
i = -1;
goto oomem;
}
}
oomem:
h_free((ptr_t)ptr);
h_free(ptr);
done:
free(line);
(void) fclose(fp);
return (i);
return i;
}
/* history_save():
/* history_save_fp():
* TYPE(History) save function
*/
private int
history_save(TYPE(History) *h, const char *fname)
static int
history_save_fp(TYPE(History) *h, FILE *fp)
{
FILE *fp;
TYPE(HistEvent) ev;
int i = -1, retval;
size_t len, max_size;
char *ptr;
#ifdef WIDECHAR
const char *str;
#ifndef NARROWCHAR
static ct_buffer_t conv;
#endif
if ((fp = fopen(fname, "w")) == NULL)
return (-1);
if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1)
goto done;
if (fputs(hist_cookie, fp) == EOF)
goto done;
ptr = h_malloc(max_size = 1024);
ptr = h_malloc((max_size = 1024) * sizeof(*ptr));
if (ptr == NULL)
goto done;
for (i = 0, retval = HLAST(h, &ev);
retval != -1;
retval = HPREV(h, &ev), i++) {
len = Strlen(ev.str) * 4;
if (len >= max_size) {
str = ct_encode_string(ev.str, &conv);
len = strlen(str) * 4 + 1;
if (len > max_size) {
char *nptr;
max_size = (len + 1024) & ~1023;
nptr = h_realloc(ptr, max_size);
max_size = (len + 1024) & (size_t)~1023;
nptr = h_realloc(ptr, max_size * sizeof(*ptr));
if (nptr == NULL) {
i = -1;
goto oomem;
}
ptr = nptr;
}
(void) strvis(ptr, ct_encode_string(ev.str, &conv), VIS_WHITE);
(void) strvis(ptr, str, VIS_WHITE);
(void) fprintf(fp, "%s\n", ptr);
}
oomem:
h_free((ptr_t)ptr);
h_free(ptr);
done:
(void) fclose(fp);
return (i);
return i;
}
/* history_save():
* History save function
*/
static int
history_save(TYPE(History) *h, const char *fname)
{
FILE *fp;
int i;
if ((fp = fopen(fname, "w")) == NULL)
return -1;
i = history_save_fp(h, fp);
(void) fclose(fp);
return i;
}
/* history_prev_event():
* Find the previous event, with number given
*/
private int
static int
history_prev_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
{
int retval;
for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
if (ev->num == num)
return (0);
return 0;
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
return -1;
}
private int
static int
history_next_evdata(TYPE(History) *h, TYPE(HistEvent) *ev, int num, void **d)
{
int retval;
@@ -859,35 +913,35 @@ history_next_evdata(TYPE(History) *h, TYPE(HistEvent) *ev, int num, void **d)
if (ev->num == num) {
if (d)
*d = ((history_t *)h->h_ref)->cursor->data;
return (0);
return 0;
}
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
return -1;
}
/* history_next_event():
* Find the next event, with number given
*/
private int
static int
history_next_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
{
int retval;
for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev))
if (ev->num == num)
return (0);
return 0;
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
return -1;
}
/* history_prev_string():
* Find the previous event beginning with string
*/
private int
static int
history_prev_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
{
size_t len = Strlen(str);
@@ -895,17 +949,17 @@ history_prev_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev))
if (Strncmp(str, ev->str, len) == 0)
return (0);
return 0;
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
return -1;
}
/* history_next_string():
* Find the next event beginning with string
*/
private int
static int
history_next_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
{
size_t len = Strlen(str);
@@ -913,10 +967,10 @@ history_next_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
if (Strncmp(str, ev->str, len) == 0)
return (0);
return 0;
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
return -1;
}
@@ -1013,6 +1067,12 @@ FUNW(history)(TYPE(History) *h, TYPE(HistEvent) *ev, int fun, ...)
he_seterrev(ev, _HE_HIST_WRITE);
break;
case H_SAVE_FP:
retval = history_save_fp(h, va_arg(va, FILE *));
if (retval == -1)
he_seterrev(ev, _HE_HIST_WRITE);
break;
case H_PREV_EVENT:
retval = history_prev_event(h, ev, va_arg(va, int));
break;
@@ -1033,7 +1093,7 @@ FUNW(history)(TYPE(History) *h, TYPE(HistEvent) *ev, int fun, ...)
{
TYPE(History) hf;
hf.h_ref = va_arg(va, ptr_t);
hf.h_ref = va_arg(va, void *);
h->h_ent = -1;
hf.h_first = va_arg(va, history_gfun_t);
hf.h_next = va_arg(va, history_gfun_t);