PR/4257: Jaromir Dolecek: history() has no generic error handling and isn't

reentrant. This changes the interface of the history function, so we need
a major number bump.
This commit is contained in:
christos 1997-10-14 15:05:49 +00:00
parent b0e76afee4
commit a7db9a7942
6 changed files with 333 additions and 172 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: editline.3,v 1.5 1997/07/30 23:57:36 jtc Exp $
.\" $NetBSD: editline.3,v 1.6 1997/10/14 15:05:49 christos Exp $
.\"
.\" Copyright (c) 1997 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -87,8 +87,8 @@
.Fn history_init
.Ft void
.Fn history_end "History *h"
.Ft HistEvent *
.Fn history "History h" "int op" "..."
.Ft int
.Fn history "History h" "HistEvent *ev" "int op" "..."
.Sh DESCRIPTION
The
.Nm
@ -434,14 +434,18 @@ Perform operation
.Fa op
on the history list, with optional arguments as needed by the
operation.
.Fa ev
is changed accordingly to operation.
The following values for
.Fa op
are supported, along with the required argument list:
.Bl -tag -width 4n
.It Dv H_EVENT , Fa "int size"
.It Dv H_SETMAXSIZE , Fa "int size"
Set size of history to
.Fa size
elements.
.It Dv H_GETSIZE
Get number of events currently in history.
.It Dv H_END
Cleans up and finishes with
.Fa h ,
@ -506,6 +510,13 @@ Save the history list to
.El
.\"XXX.Sh EXAMPLES
.\"XXX: provide some examples
.Sh RETURN VALUES
.Ft history
function returns 0 if the operation
.Ft op
succeeds, otherwise -1 is returned and
.Ft ev
is updated to contain more detailes about error.
.Sh SEE ALSO
.Xr editrc 5 ,
.Xr sh 1 ,

View File

@ -1,4 +1,4 @@
/* $NetBSD: hist.c,v 1.3 1997/07/06 18:25:26 christos Exp $ */
/* $NetBSD: hist.c,v 1.4 1997/10/14 15:05:50 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -41,7 +41,7 @@
#if 0
static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: hist.c,v 1.3 1997/07/06 18:25:26 christos Exp $");
__RCSID("$NetBSD: hist.c,v 1.4 1997/10/14 15:05:50 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -172,6 +172,6 @@ hist_list(el, argc, argv)
if (el->el_history.ref == NULL)
return -1;
for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
(void) fprintf(el->el_outfile, "%d %s", el->el_history.ev->num, str);
(void) fprintf(el->el_outfile, "%d %s", el->el_history.ev.num, str);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: hist.h,v 1.3 1997/01/11 06:47:56 lukem Exp $ */
/* $NetBSD: hist.h,v 1.4 1997/10/14 15:05:52 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -46,7 +46,7 @@
#include "histedit.h"
typedef const HistEvent * (*hist_fun_t) __P((ptr_t, int, ...));
typedef int (*hist_fun_t) __P((ptr_t, HistEvent *, int, ...));
typedef struct el_history_t {
char *buf; /* The history buffer */
@ -54,13 +54,12 @@ typedef struct el_history_t {
int eventno; /* Event we are looking for */
ptr_t ref; /* Argument for history fcns */
hist_fun_t fun; /* Event access */
const HistEvent *ev; /* Event cookie */
HistEvent ev; /* Event cookie */
} el_history_t;
#define HIST_FUN(el, fn, arg) \
((((el)->el_history.ev = \
(*(el)->el_history.fun)((el)->el_history.ref, fn, arg)) == NULL) ? \
NULL : (el)->el_history.ev->str)
((((*(el)->el_history.fun) ((el)->el_history.ref, &(el)->el_history.ev, \
fn, arg)) == -1) ? NULL : (el)->el_history.ev.str)
#define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL)
#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL)

View File

@ -1,4 +1,4 @@
/* $NetBSD: histedit.h,v 1.5 1997/04/11 17:52:45 christos Exp $ */
/* $NetBSD: histedit.h,v 1.6 1997/10/14 15:05:53 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -145,20 +145,20 @@ void el_deletestr __P((EditLine *, int));
typedef struct history History;
typedef struct HistEvent {
int num;
const char *str;
int num;
const char *str;
} HistEvent;
/*
* History access functions.
*/
History * history_init __P((void));
void history_end __P((History *));
History * history_init __P((void));
void history_end __P((History *));
const HistEvent * history __P((History *, int, ...));
int history __P((History *, HistEvent *, int, ...));
#define H_FUNC 0 /* , UTSL */
#define H_EVENT 1 /* , const int); */
#define H_SETMAXSIZE 1 /* , const int); */
#define H_FIRST 2 /* , void); */
#define H_LAST 3 /* , void); */
#define H_PREV 4 /* , void); */
@ -174,5 +174,6 @@ const HistEvent * history __P((History *, int, ...));
#define H_LOAD 14 /* , const char *); */
#define H_SAVE 15 /* , const char *); */
#define H_CLEAR 16 /* , void); */
#define H_GETSIZE 17 /* , void); */
#endif /* _h_editline */

View File

@ -1,4 +1,4 @@
/* $NetBSD: history.c,v 1.6 1997/07/06 18:25:27 christos Exp $ */
/* $NetBSD: history.c,v 1.7 1997/10/14 15:05:54 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -41,7 +41,7 @@
#if 0
static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: history.c,v 1.6 1997/07/06 18:25:27 christos Exp $");
__RCSID("$NetBSD: history.c,v 1.7 1997/10/14 15:05:54 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -62,9 +62,9 @@ static const char hist_cookie[] = "_HiStOrY_V1_\n";
#include "histedit.h"
typedef const HistEvent * (*history_gfun_t) __P((ptr_t));
typedef const HistEvent * (*history_efun_t) __P((ptr_t, const char *));
typedef void (*history_vfun_t) __P((ptr_t));
typedef int (*history_gfun_t) __P((ptr_t, HistEvent *));
typedef int (*history_efun_t) __P((ptr_t, HistEvent *, const char *));
typedef void (*history_vfun_t) __P((ptr_t, HistEvent *));
struct history {
ptr_t h_ref; /* Argument for history fcns */
@ -78,27 +78,28 @@ struct history {
history_efun_t h_add; /* Append to an element */
};
#define HNEXT(h) (*(h)->h_next)((h)->h_ref)
#define HFIRST(h) (*(h)->h_first)((h)->h_ref)
#define HPREV(h) (*(h)->h_prev)((h)->h_ref)
#define HLAST(h) (*(h)->h_last)((h)->h_ref)
#define HCURR(h) (*(h)->h_curr)((h)->h_ref)
#define HCLEAR(h) (*(h)->h_clear)((h)->h_ref)
#define HENTER(h, str) (*(h)->h_enter)((h)->h_ref, str)
#define HADD(h, str) (*(h)->h_add)((h)->h_ref, str)
#define HNEXT(h, ev) (*(h)->h_next)((h)->h_ref, ev)
#define HFIRST(h, ev) (*(h)->h_first)((h)->h_ref, ev)
#define HPREV(h, ev) (*(h)->h_prev)((h)->h_ref, ev)
#define HLAST(h, ev) (*(h)->h_last)((h)->h_ref, ev)
#define HCURR(h, ev) (*(h)->h_curr)((h)->h_ref, ev)
#define HCLEAR(h, ev) (*(h)->h_clear)((h)->h_ref, ev)
#define HENTER(h, ev, str) (*(h)->h_enter)((h)->h_ref, ev, str)
#define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str)
#define h_malloc(a) malloc(a)
#define h_free(a) free(a)
private int history_set_num __P((History *, int));
private int history_set_fun __P((History *, History *));
private int history_load __P((History *, const char *));
private int history_save __P((History *, const char *));
private const HistEvent *history_prev_event __P((History *, int));
private const HistEvent *history_next_event __P((History *, int));
private const HistEvent *history_next_string __P((History *, const char *));
private const HistEvent *history_prev_string __P((History *, const char *));
private int history_set_num __P((History *, HistEvent *, int));
private int history_get_size __P((History *, HistEvent *));
private int history_set_fun __P((History *, History *));
private int history_load __P((History *, const char *));
private int history_save __P((History *, const char *));
private int history_prev_event __P((History *, HistEvent *, int));
private int history_next_event __P((History *, HistEvent *, int));
private int history_next_string __P((History *, HistEvent *, const char *));
private int history_prev_string __P((History *, HistEvent *, const char *));
/***********************************************************************/
@ -117,117 +118,192 @@ typedef struct history_t {
hentry_t *cursor; /* Current element in the list */
int max; /* Maximum number of events */
int cur; /* Current number of events */
int eventno; /* Current event number */
int eventid; /* For generation of unique event id */
} history_t;
private const HistEvent *history_def_first __P((ptr_t));
private const HistEvent *history_def_last __P((ptr_t));
private const HistEvent *history_def_next __P((ptr_t));
private const HistEvent *history_def_prev __P((ptr_t));
private const HistEvent *history_def_curr __P((ptr_t));
private const HistEvent *history_def_enter __P((ptr_t, const char *));
private const HistEvent *history_def_add __P((ptr_t, const char *));
private void history_def_init __P((ptr_t *, int));
private void history_def_clear __P((ptr_t));
private const HistEvent *history_def_insert __P((history_t *, const char *));
private void history_def_delete __P((history_t *, hentry_t *));
private int history_def_first __P((ptr_t, HistEvent *));
private int history_def_last __P((ptr_t, HistEvent *));
private int history_def_next __P((ptr_t, HistEvent *));
private int history_def_prev __P((ptr_t, HistEvent *));
private int history_def_curr __P((ptr_t, HistEvent *));
private int history_def_enter __P((ptr_t, HistEvent *, const char *));
private int history_def_add __P((ptr_t, HistEvent *, const char *));
private void history_def_init __P((ptr_t *, HistEvent *, int));
private void history_def_clear __P((ptr_t, HistEvent *));
private int history_def_insert __P((history_t *, HistEvent *,const char *));
private void history_def_delete __P((history_t *, HistEvent *, hentry_t *));
#define history_def_set(p, num) (void) (((history_t *) p)->max = (num))
#define history_def_getsize(p) (((history_t *) p)->cur)
#define he_strerror(code) he_errlist[code]
#define he_seterrev(evp, code) {\
evp->num = code;\
evp->str = he_strerror(code);\
}
/* error messages */
static const char *const he_errlist[] = {
"OK",
"malloc() failed",
"first event not found",
"last event not found",
"empty list",
"no next event",
"no previous event",
"current event is invalid",
"event not found",
"can't read history from file",
"can't write history",
"required parameter(s) not supplied",
"history size negative",
"function not allowed with other history-functions-set the default",
"bad parameters"
};
/* error codes */
#define _HE_OK 0
#define _HE_UNKNOWN 1
#define _HE_MALLOC_FAILED 2
#define _HE_FIRST_NOTFOUND 3
#define _HE_LAST_NOTFOUND 4
#define _HE_EMPTY_LIST 5
#define _HE_END_REACHED 6
#define _HE_START_REACHED 7
#define _HE_CURR_INVALID 8
#define _HE_NOT_FOUND 9
#define _HE_HIST_READ 10
#define _HE_HIST_WRITE 11
#define _HE_PARAM_MISSING 12
#define _HE_SIZE_NEGATIVE 13
#define _HE_NOT_ALLOWED 14
#define _HE_BAD_PARAM 15
/* history_def_first():
* Default function to return the first event in the history.
*/
private const HistEvent *
history_def_first(p)
private int
history_def_first(p, ev)
ptr_t p;
HistEvent *ev;
{
history_t *h = (history_t *) p;
h->cursor = h->list.next;
if (h->cursor != &h->list)
return &h->cursor->ev;
else
return NULL;
*ev = h->cursor->ev;
else {
he_seterrev(ev, _HE_FIRST_NOTFOUND);
return -1;
}
return 0;
}
/* history_def_last():
* Default function to return the last event in the history.
*/
private const HistEvent *
history_def_last(p)
private int
history_def_last(p, ev)
ptr_t p;
HistEvent *ev;
{
history_t *h = (history_t *) p;
h->cursor = h->list.prev;
if (h->cursor != &h->list)
return &h->cursor->ev;
else
return NULL;
*ev = h->cursor->ev;
else {
he_seterrev(ev, _HE_LAST_NOTFOUND);
return -1;
}
return 0;
}
/* history_def_next():
* Default function to return the next event in the history.
*/
private const HistEvent *
history_def_next(p)
private int
history_def_next(p, ev)
ptr_t p;
HistEvent *ev;
{
history_t *h = (history_t *) p;
if (h->cursor != &h->list)
h->cursor = h->cursor->next;
else
return NULL;
else {
he_seterrev(ev, _HE_EMPTY_LIST);
return -1;
}
if (h->cursor != &h->list)
return &h->cursor->ev;
else
return NULL;
*ev = h->cursor->ev;
else {
he_seterrev(ev, _HE_END_REACHED);
return -1;
}
return 0;
}
/* history_def_prev():
* Default function to return the previous event in the history.
*/
private const HistEvent *
history_def_prev(p)
private int
history_def_prev(p, ev)
ptr_t p;
HistEvent *ev;
{
history_t *h = (history_t *) p;
if (h->cursor != &h->list)
h->cursor = h->cursor->prev;
else
return NULL;
else {
he_seterrev(ev, (h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST);
return -1;
}
if (h->cursor != &h->list)
return &h->cursor->ev;
else
return NULL;
*ev = h->cursor->ev;
else {
he_seterrev(ev, _HE_START_REACHED);
return -1;
}
return 0;
}
/* history_def_curr():
* Default function to return the current event in the history.
*/
private const HistEvent *
history_def_curr(p)
private int
history_def_curr(p, ev)
ptr_t p;
HistEvent *ev;
{
history_t *h = (history_t *) p;
if (h->cursor != &h->list)
return &h->cursor->ev;
else
return NULL;
*ev = h->cursor->ev;
else {
he_seterrev(ev, (h->cur > 0) ? _HE_CURR_INVALID : _HE_EMPTY_LIST);
return -1;
}
return 0;
}
/* history_def_add():
* Append string to element
*/
private const HistEvent *
history_def_add(p, str)
private int
history_def_add(p, ev, str)
ptr_t p;
HistEvent *ev;
const char *str;
{
history_t *h = (history_t *) p;
@ -235,14 +311,19 @@ history_def_add(p, str)
char *s;
if (h->cursor == &h->list)
return (history_def_enter(p, str));
return (history_def_enter(p, ev, str));
len = strlen(h->cursor->ev.str) + strlen(str) + 1;
s = (char *) h_malloc(len);
(void)strcpy(s, h->cursor->ev.str); /* XXX strcpy is safe */
if (!s) {
he_seterrev(ev, _HE_MALLOC_FAILED);
return -1;
}
(void)strcpy(s, h->cursor->ev.str); /* XXX strcpy is safe */
(void)strcat(s, str); /* XXX strcat is safe */
h_free((ptr_t) h->cursor->ev.str);
h->cursor->ev.str = s;
return &h->cursor->ev;
*ev = h->cursor->ev;
return 0;
}
@ -250,8 +331,9 @@ history_def_add(p, str)
* Delete element hp of the h list
*/
private void
history_def_delete(h, hp)
history_def_delete(h, ev, hp)
history_t *h;
HistEvent *ev;
hentry_t *hp;
{
if (hp == &h->list)
@ -267,45 +349,53 @@ history_def_delete(h, hp)
/* history_def_insert():
* Insert element with string str in the h list
*/
private const HistEvent *
history_def_insert(h, str)
private int
history_def_insert(h, ev, str)
history_t *h;
HistEvent *ev;
const char *str;
{
h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t));
h->cursor->ev.str = strdup(str);
if (h->cursor)
h->cursor->ev.str = strdup(str);
if (!h->cursor || !h->cursor->ev.str) {
he_seterrev(ev, _HE_MALLOC_FAILED);
return -1;
}
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;
h->cur++;
return &h->cursor->ev;
*ev = h->cursor->ev;
return 0;
}
/* history_def_enter():
* Default function to enter an item in the history
*/
private const HistEvent *
history_def_enter(p, str)
private int
history_def_enter(p, ev, str)
ptr_t p;
HistEvent *ev;
const char *str;
{
history_t *h = (history_t *) p;
const HistEvent *ev;
ev = history_def_insert(h, str);
((HistEvent*) ev)->num = ++h->eventno;
if (history_def_insert(h, ev, str) == -1)
return -1; /* error, keep error message */
/*
* Always keep at least one entry.
* This way we don't have to check for the empty list.
*/
while (h->cur > h->max + 1)
history_def_delete(h, h->list.prev);
return ev;
while (h->cur - 1 > h->max)
history_def_delete(h, ev, h->list.prev);
return 0;
}
@ -313,14 +403,15 @@ history_def_enter(p, str)
* Default history initialization function
*/
private void
history_def_init(p, n)
history_def_init(p, ev, n)
ptr_t *p;
HistEvent *ev;
int n;
{
history_t *h = (history_t *) h_malloc(sizeof(history_t));
if (n <= 0)
n = 0;
h->eventno = 0;
h->eventid = 0;
h->cur = 0;
h->max = n;
h->list.next = h->list.prev = &h->list;
@ -335,14 +426,15 @@ history_def_init(p, n)
* Default history cleanup function
*/
private void
history_def_clear(p)
history_def_clear(p, ev)
ptr_t p;
HistEvent *ev;
{
history_t *h = (history_t *) p;
while (h->list.prev != &h->list)
history_def_delete(h, h->list.prev);
h->eventno = 0;
history_def_delete(h, ev, h->list.prev);
h->eventid = 0;
h->cur = 0;
}
@ -358,8 +450,9 @@ public History *
history_init()
{
History *h = (History *) h_malloc(sizeof(History));
HistEvent ev;
history_def_init(&h->h_ref, 0);
history_def_init(&h->h_ref, &ev, 0);
h->h_next = history_def_next;
h->h_first = history_def_first;
@ -381,8 +474,9 @@ public void
history_end(h)
History *h;
{
HistEvent ev;
if (h->h_next == history_def_next)
history_def_clear(h->h_ref);
history_def_clear(h->h_ref, &ev);
}
@ -391,30 +485,65 @@ history_end(h)
* Set history number of events
*/
private int
history_set_num(h, num)
history_set_num(h, ev, num)
History *h;
HistEvent *ev;
int num;
{
if (h->h_next != history_def_next || num < 0)
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return -1;
}
if (num < 0) {
he_seterrev(ev, _HE_BAD_PARAM);
return -1;
}
history_def_set(h->h_ref, num);
return 0;
}
/* history_get_size():
* Get number of events currently in history
*/
private int
history_get_size(h, ev)
History *h;
HistEvent *ev;
{
int retval=0;
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return -1;
}
retval = history_def_getsize(h->h_ref);
if (retval < -1) {
he_seterrev(ev, _HE_SIZE_NEGATIVE);
return -1;
}
ev->num = retval;
return 0;
}
/* history_set_fun():
* Set history functions
*/
private int
history_set_fun(h, nh)
History *h, *nh;
History *h;
History *nh;
{
HistEvent ev;
if (nh->h_first == NULL || nh->h_next == NULL ||
nh->h_last == NULL || nh->h_prev == NULL || nh->h_curr == NULL ||
nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL ||
nh->h_ref == NULL) {
if (h->h_next != history_def_next) {
history_def_init(&h->h_ref, 0);
history_def_init(&h->h_ref, &ev, 0);
h->h_first = history_def_first;
h->h_next = history_def_next;
h->h_last = history_def_last;
@ -428,7 +557,7 @@ history_set_fun(h, nh)
}
if (h->h_next == history_def_next)
history_def_clear(h->h_ref);
history_def_clear(h->h_ref, &ev);
h->h_first = nh->h_first;
h->h_next = nh->h_next;
@ -455,6 +584,7 @@ history_load(h, fname)
char *line;
size_t sz;
int i = -1;
HistEvent ev;
if ((fp = fopen(fname, "r")) == NULL)
return i;
@ -468,7 +598,7 @@ history_load(h, fname)
for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) {
char c = line[sz];
line[sz] = '\0';
HENTER(h, line);
HENTER(h, &ev, line);
line[sz] = c;
}
@ -487,15 +617,15 @@ history_save(h, fname)
const char *fname;
{
FILE *fp;
const HistEvent *ev;
int i = 0;
HistEvent ev;
int i = 0, retval;
if ((fp = fopen(fname, "w")) == NULL)
return -1;
(void) fputs(hist_cookie, fp);
for (ev = HLAST(h); ev != NULL; ev = HPREV(h), i++)
(void) fprintf(fp, "%s", ev->str);
for (retval = HLAST(h, &ev); retval != -1; retval = HPREV(h, &ev), i++)
(void) fprintf(fp, "%s", ev.str);
(void) fclose(fp);
return i;
}
@ -504,31 +634,37 @@ history_save(h, fname)
/* history_prev_event():
* Find the previous event, with number given
*/
private const HistEvent *
history_prev_event(h, num)
private int
history_prev_event(h, ev, num)
History *h;
HistEvent *ev;
int num;
{
const HistEvent *ev;
for (ev = HCURR(h); ev != NULL; ev = HPREV(h))
int retval;
for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
if (ev->num == num)
return ev;
return NULL;
return 0;
he_seterrev(ev, _HE_NOT_FOUND);
return -1;
}
/* history_next_event():
* Find the next event, with number given
*/
private const HistEvent *
history_next_event(h, num)
private int
history_next_event(h, ev, num)
History *h;
HistEvent *ev;
int num;
{
const HistEvent *ev;
for (ev = HCURR(h); ev != NULL; ev = HNEXT(h))
int retval;
for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev))
if (ev->num == num)
return ev;
return 0;
he_seterrev(ev, _HE_NOT_FOUND);
return NULL;
}
@ -536,18 +672,21 @@ history_next_event(h, num)
/* history_prev_string():
* Find the previous event beginning with string
*/
private const HistEvent *
history_prev_string(h, str)
private int
history_prev_string(h, ev, str)
History *h;
HistEvent *ev;
const char* str;
{
const HistEvent *ev;
size_t len = strlen(str);
int retval;
for (ev = HCURR(h); ev != NULL; ev = HNEXT(h))
for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev))
if (strncmp(str, ev->str, len) == 0)
return ev;
return NULL;
return 0;
he_seterrev(ev, _HE_NOT_FOUND);
return -1;
}
@ -556,113 +695,119 @@ history_prev_string(h, str)
/* history_next_string():
* Find the next event beginning with string
*/
private const HistEvent *
history_next_string(h, str)
private int
history_next_string(h, ev, str)
History *h;
HistEvent *ev;
const char* str;
{
const HistEvent *ev;
size_t len = strlen(str);
int retval;
for (ev = HCURR(h); ev != NULL; ev = HPREV(h))
for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
if (strncmp(str, ev->str, len) == 0)
return ev;
return NULL;
return 0;
he_seterrev(ev, _HE_NOT_FOUND);
return -1;
}
/* history():
* User interface to history functions.
*/
const HistEvent *
int
#ifdef __STDC__
history(History *h, int fun, ...)
history(History *h, HistEvent *ev, int fun, ...)
#else
history(va_alist)
va_dcl
#endif
{
va_list va;
const HistEvent *ev = NULL;
const char *str;
static HistEvent sev = { 0, "" };
int retval;
#ifdef __STDC__
va_start(va, fun);
#else
History *h;
HistEvent *ev;
int fun;
va_start(va);
h = va_arg(va, History *);
ev = va_arg(va, HistEvent *);
fun = va_arg(va, int);
#endif
he_seterrev(ev, _HE_OK);
switch (fun) {
case H_ADD:
str = va_arg(va, const char *);
ev = HADD(h, str);
retval = HADD(h, ev, str);
break;
case H_ENTER:
str = va_arg(va, const char *);
ev = HENTER(h, str);
retval = HENTER(h, ev, str);
break;
case H_FIRST:
ev = HFIRST(h);
retval = HFIRST(h, ev);
break;
case H_NEXT:
ev = HNEXT(h);
retval = HNEXT(h, ev);
break;
case H_LAST:
ev = HLAST(h);
retval = HLAST(h, ev);
break;
case H_PREV:
ev = HPREV(h);
retval = HPREV(h, ev);
break;
case H_CURR:
ev = HCURR(h);
retval = HCURR(h, ev);
break;
case H_CLEAR:
HCLEAR(h);
HCLEAR(h, ev);
retval = 0;
break;
case H_LOAD:
sev.num = history_load(h, va_arg(va, const char *));
ev = &sev;
retval = history_load(h, va_arg(va, const char *));
if (retval == -1)
he_seterrev(ev, _HE_HIST_READ);
break;
case H_SAVE:
sev.num = history_save(h, va_arg(va, const char *));
ev = &sev;
retval = history_save(h, va_arg(va, const char *));
if (retval == -1)
he_seterrev(ev, _HE_HIST_WRITE);
break;
case H_PREV_EVENT:
ev = history_prev_event(h, va_arg(va, int));
retval = history_prev_event(h, ev, va_arg(va, int));
break;
case H_NEXT_EVENT:
ev = history_next_event(h, va_arg(va, int));
retval = history_next_event(h, ev, va_arg(va, int));
break;
case H_PREV_STR:
ev = history_prev_string(h, va_arg(va, const char*));
retval = history_prev_string(h, ev, va_arg(va, const char*));
break;
case H_NEXT_STR:
ev = history_next_string(h, va_arg(va, const char*));
retval = history_next_string(h, ev, va_arg(va, const char*));
break;
case H_EVENT:
if (history_set_num(h, va_arg(va, int)) == 0) {
sev.num = -1;
ev = &sev;
}
case H_SETMAXSIZE:
retval = history_set_num(h, ev, va_arg(va, int));
break;
case H_FUNC:
@ -678,20 +823,25 @@ history(va_alist)
hf.h_enter = va_arg(va, history_efun_t);
hf.h_add = va_arg(va, history_efun_t);
if (history_set_fun(h, &hf) == 0) {
sev.num = -1;
ev = &sev;
}
if ((retval = history_set_fun(h, &hf)) == -1)
he_seterrev(ev, _HE_PARAM_MISSING);
}
break;
case H_END:
history_end(h);
retval = 0;
break;
case H_GETSIZE:
retval = history_get_size(h, ev);
break;
default:
retval = -1;
he_seterrev(ev, _HE_UNKNOWN);
break;
}
va_end(va);
return ev;
return retval;
}

View File

@ -1,2 +1,2 @@
major=0
major=1
minor=0