123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875 |
- /* $NetBSD: history.c,v 1.19 2002/03/18 16:00:54 christos Exp $ */
- /*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
- #include "config.h"
- #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.19 2002/03/18 16:00:54 christos Exp $");
- #endif
- #endif /* not lint && not SCCSID */
- /*
- * hist.c: History access functions
- */
- #include <string.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #ifdef HAVE_VIS_H
- #include <vis.h>
- #else
- #include "np/vis.h"
- #endif
- #include <sys/stat.h>
- static const char hist_cookie[] = "_HiStOrY_V2_\n";
- #include "histedit.h"
- typedef int (*history_gfun_t)(ptr_t, HistEvent *);
- typedef int (*history_efun_t)(ptr_t, HistEvent *, const char *);
- typedef void (*history_vfun_t)(ptr_t, HistEvent *);
- typedef int (*history_sfun_t)(ptr_t, HistEvent *, const int);
- struct history {
- ptr_t 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 */
- history_gfun_t h_last; /* Get the last element */
- history_gfun_t h_prev; /* Get the previous element */
- history_gfun_t h_curr; /* Get the current element */
- history_sfun_t h_set; /* Set the current element */
- history_vfun_t h_clear; /* Clear the history list */
- history_efun_t h_enter; /* Add an element */
- history_efun_t h_add; /* Append to an element */
- };
- #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 HSET(h, ev, n) (*(h)->h_set)((h)->h_ref, ev, n)
- #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_realloc(a, b) realloc((a), (b))
- #define h_free(a) free(a)
- typedef struct {
- int num;
- char *str;
- } HistEventPrivate;
- private int history_setsize(History *, HistEvent *, int);
- private int history_getsize(History *, HistEvent *);
- private int history_set_fun(History *, History *);
- private int history_load(History *, const char *);
- private int history_save(History *, const char *);
- private int history_prev_event(History *, HistEvent *, int);
- private int history_next_event(History *, HistEvent *, int);
- private int history_next_string(History *, HistEvent *, const char *);
- private int history_prev_string(History *, HistEvent *, const char *);
- /***********************************************************************/
- /*
- * Builtin- history implementation
- */
- typedef struct hentry_t {
- HistEvent ev; /* What we return */
- struct hentry_t *next; /* Next entry */
- struct hentry_t *prev; /* Previous entry */
- } hentry_t;
- typedef struct history_t {
- hentry_t list; /* Fake list header element */
- hentry_t *cursor; /* Current element in the list */
- int max; /* Maximum number of events */
- int cur; /* Current number of events */
- int eventid; /* For generation of unique event id */
- } history_t;
- private int history_def_first(ptr_t, HistEvent *);
- private int history_def_last(ptr_t, HistEvent *);
- private int history_def_next(ptr_t, HistEvent *);
- private int history_def_prev(ptr_t, HistEvent *);
- private int history_def_curr(ptr_t, HistEvent *);
- private int history_def_set(ptr_t, HistEvent *, const int n);
- private int history_def_enter(ptr_t, HistEvent *, const char *);
- private int history_def_add(ptr_t, HistEvent *, const char *);
- private void history_def_init(ptr_t *, HistEvent *, int);
- private void history_def_clear(ptr_t, HistEvent *);
- private int history_def_insert(history_t *, HistEvent *, const char *);
- private void history_def_delete(history_t *, HistEvent *, hentry_t *);
- #define history_def_setsize(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",
- "unknown error",
- "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 int
- history_def_first(ptr_t p, HistEvent *ev)
- {
- history_t *h = (history_t *) p;
- h->cursor = h->list.next;
- if (h->cursor != &h->list)
- *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 int
- history_def_last(ptr_t p, HistEvent *ev)
- {
- history_t *h = (history_t *) p;
- h->cursor = h->list.prev;
- if (h->cursor != &h->list)
- *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 int
- history_def_next(ptr_t p, HistEvent *ev)
- {
- history_t *h = (history_t *) p;
- if (h->cursor != &h->list)
- h->cursor = h->cursor->next;
- else {
- he_seterrev(ev, _HE_EMPTY_LIST);
- return (-1);
- }
- if (h->cursor != &h->list)
- *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 int
- history_def_prev(ptr_t p, HistEvent *ev)
- {
- history_t *h = (history_t *) p;
- if (h->cursor != &h->list)
- h->cursor = h->cursor->prev;
- else {
- he_seterrev(ev,
- (h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST);
- return (-1);
- }
- if (h->cursor != &h->list)
- *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 int
- history_def_curr(ptr_t p, HistEvent *ev)
- {
- history_t *h = (history_t *) p;
- if (h->cursor != &h->list)
- *ev = h->cursor->ev;
- else {
- he_seterrev(ev,
- (h->cur > 0) ? _HE_CURR_INVALID : _HE_EMPTY_LIST);
- return (-1);
- }
- return (0);
- }
- /* history_def_set():
- * Default function to set the current event in the history to the
- * given one.
- */
- private int
- history_def_set(ptr_t p, HistEvent *ev, const int n)
- {
- history_t *h = (history_t *) p;
- if (h->cur == 0) {
- he_seterrev(ev, _HE_EMPTY_LIST);
- return (-1);
- }
- if (h->cursor == &h->list || h->cursor->ev.num != n) {
- for (h->cursor = h->list.next; h->cursor != &h->list;
- h->cursor = h->cursor->next)
- if (h->cursor->ev.num == n)
- break;
- }
- if (h->cursor == &h->list) {
- he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
- }
- return (0);
- }
- /* history_def_add():
- * Append string to element
- */
- private int
- history_def_add(ptr_t p, HistEvent *ev, const char *str)
- {
- history_t *h = (history_t *) p;
- size_t len;
- char *s;
- HistEventPrivate *evp = (void *)&h->cursor->ev;
- if (h->cursor == &h->list)
- return (history_def_enter(p, ev, str));
- len = strlen(evp->str) + strlen(str) + 1;
- s = (char *) h_malloc(len);
- if (!s) {
- he_seterrev(ev, _HE_MALLOC_FAILED);
- return (-1);
- }
- (void) strlcpy(s, h->cursor->ev.str, len);
- (void) strlcat(s, str, len);
- h_free(evp->str);
- evp->str = s;
- *ev = h->cursor->ev;
- return (0);
- }
- /* history_def_delete():
- * Delete element hp of the h list
- */
- /* ARGSUSED */
- private void
- history_def_delete(history_t *h, HistEvent *ev, hentry_t *hp)
- {
- HistEventPrivate *evp = (void *)&hp->ev;
- if (hp == &h->list)
- abort();
- hp->prev->next = hp->next;
- hp->next->prev = hp->prev;
- h_free((ptr_t) evp->str);
- h_free(hp);
- h->cur--;
- }
- /* history_def_insert():
- * Insert element with string str in the h list
- */
- private int
- history_def_insert(history_t *h, HistEvent *ev, const char *str)
- {
- h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t));
- 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++;
- *ev = h->cursor->ev;
- return (0);
- }
- /* history_def_enter():
- * Default function to enter an item in the history
- */
- private int
- history_def_enter(ptr_t p, HistEvent *ev, const char *str)
- {
- history_t *h = (history_t *) p;
- 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 && h->cur > 0)
- history_def_delete(h, ev, h->list.prev);
- return (0);
- }
- /* history_def_init():
- * Default history initialization function
- */
- /* ARGSUSED */
- private void
- history_def_init(ptr_t *p, HistEvent *ev, int n)
- {
- history_t *h = (history_t *) h_malloc(sizeof(history_t));
- if (n <= 0)
- n = 0;
- h->eventid = 0;
- h->cur = 0;
- h->max = n;
- h->list.next = h->list.prev = &h->list;
- h->list.ev.str = NULL;
- h->list.ev.num = 0;
- h->cursor = &h->list;
- *p = (ptr_t) h;
- }
- /* history_def_clear():
- * Default history cleanup function
- */
- private void
- history_def_clear(ptr_t p, HistEvent *ev)
- {
- history_t *h = (history_t *) p;
- while (h->list.prev != &h->list)
- history_def_delete(h, ev, h->list.prev);
- h->eventid = 0;
- h->cur = 0;
- }
- /************************************************************************/
- /* history_init():
- * Initialization function.
- */
- public History *
- history_init(void)
- {
- History *h = (History *) h_malloc(sizeof(History));
- HistEvent ev;
- history_def_init(&h->h_ref, &ev, 0);
- h->h_ent = -1;
- h->h_next = history_def_next;
- h->h_first = history_def_first;
- h->h_last = history_def_last;
- h->h_prev = history_def_prev;
- h->h_curr = history_def_curr;
- h->h_set = history_def_set;
- h->h_clear = history_def_clear;
- h->h_enter = history_def_enter;
- h->h_add = history_def_add;
- return (h);
- }
- /* history_end():
- * clean up history;
- */
- public void
- history_end(History *h)
- {
- HistEvent ev;
- if (h->h_next == history_def_next)
- history_def_clear(h->h_ref, &ev);
- }
- /* history_setsize():
- * Set history number of events
- */
- private int
- history_setsize(History *h, HistEvent *ev, int num)
- {
- 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_setsize(h->h_ref, num);
- return (0);
- }
- /* history_getsize():
- * Get number of events currently in history
- */
- private int
- history_getsize(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(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_set == 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, &ev, 0);
- h->h_first = history_def_first;
- h->h_next = history_def_next;
- h->h_last = history_def_last;
- h->h_prev = history_def_prev;
- h->h_curr = history_def_curr;
- h->h_set = history_def_set;
- h->h_clear = history_def_clear;
- h->h_enter = history_def_enter;
- h->h_add = history_def_add;
- }
- return (-1);
- }
- if (h->h_next == history_def_next)
- history_def_clear(h->h_ref, &ev);
- h->h_ent = -1;
- h->h_first = nh->h_first;
- h->h_next = nh->h_next;
- h->h_last = nh->h_last;
- h->h_prev = nh->h_prev;
- h->h_curr = nh->h_curr;
- h->h_set = nh->h_set;
- h->h_clear = nh->h_clear;
- h->h_enter = nh->h_enter;
- h->h_add = nh->h_add;
- return (0);
- }
- /* history_load():
- * History load function
- */
- private int
- history_load(History *h, const char *fname)
- {
- FILE *fp;
- char *line;
- size_t sz, max_size;
- char *ptr;
- int i = -1;
- HistEvent ev;
- if ((fp = fopen(fname, "r")) == NULL)
- return (i);
- if ((line = fgetln(fp, &sz)) == NULL)
- goto done;
- if (strncmp(line, hist_cookie, sz) != 0)
- goto done;
- ptr = h_malloc(max_size = 1024);
- for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) {
- char c = line[sz];
- if (sz != 0 && line[sz - 1] == '\n')
- line[--sz] = '\0';
- else
- line[sz] = '\0';
- if (max_size < sz) {
- max_size = (sz + 1023) & ~1023;
- ptr = h_realloc(ptr, max_size);
- }
- (void) strunvis(ptr, line);
- line[sz] = c;
- HENTER(h, &ev, ptr);
- }
- h_free(ptr);
- done:
- (void) fclose(fp);
- return (i);
- }
- /* history_save():
- * History save function
- */
- private int
- history_save(History *h, const char *fname)
- {
- FILE *fp;
- HistEvent ev;
- int i = 0, retval;
- size_t len, max_size;
- char *ptr;
- if ((fp = fopen(fname, "w")) == NULL)
- return (-1);
- (void) fchmod(fileno(fp), S_IRUSR|S_IWUSR);
- (void) fputs(hist_cookie, fp);
- ptr = h_malloc(max_size = 1024);
- for (retval = HLAST(h, &ev);
- retval != -1;
- retval = HPREV(h, &ev), i++) {
- len = strlen(ev.str) * 4;
- if (len >= max_size) {
- max_size = (len + 1023) & 1023;
- ptr = h_realloc(ptr, max_size);
- }
- (void) strvis(ptr, ev.str, VIS_WHITE);
- (void) fprintf(fp, "%s\n", ev.str);
- }
- h_free(ptr);
- (void) fclose(fp);
- return (i);
- }
- /* history_prev_event():
- * Find the previous event, with number given
- */
- private int
- history_prev_event(History *h, HistEvent *ev, int num)
- {
- int retval;
- for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
- if (ev->num == num)
- return (0);
- he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
- }
- /* history_next_event():
- * Find the next event, with number given
- */
- private int
- history_next_event(History *h, HistEvent *ev, int num)
- {
- int retval;
- for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev))
- if (ev->num == num)
- return (0);
- he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
- }
- /* history_prev_string():
- * Find the previous event beginning with string
- */
- private int
- history_prev_string(History *h, HistEvent *ev, const char *str)
- {
- size_t len = strlen(str);
- int retval;
- for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev))
- if (strncmp(str, ev->str, len) == 0)
- return (0);
- he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
- }
- /* history_next_string():
- * Find the next event beginning with string
- */
- private int
- history_next_string(History *h, HistEvent *ev, const char *str)
- {
- size_t len = strlen(str);
- int retval;
- for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
- if (strncmp(str, ev->str, len) == 0)
- return (0);
- he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
- }
- /* history():
- * User interface to history functions.
- */
- int
- history(History *h, HistEvent *ev, int fun, ...)
- {
- va_list va;
- const char *str;
- int retval;
- va_start(va, fun);
- he_seterrev(ev, _HE_OK);
- switch (fun) {
- case H_GETSIZE:
- retval = history_getsize(h, ev);
- break;
- case H_SETSIZE:
- retval = history_setsize(h, ev, va_arg(va, int));
- break;
- case H_ADD:
- str = va_arg(va, const char *);
- retval = HADD(h, ev, str);
- break;
- case H_ENTER:
- str = va_arg(va, const char *);
- if ((retval = HENTER(h, ev, str)) != -1)
- h->h_ent = ev->num;
- break;
- case H_APPEND:
- str = va_arg(va, const char *);
- if ((retval = HSET(h, ev, h->h_ent)) != -1)
- retval = HADD(h, ev, str);
- break;
- case H_FIRST:
- retval = HFIRST(h, ev);
- break;
- case H_NEXT:
- retval = HNEXT(h, ev);
- break;
- case H_LAST:
- retval = HLAST(h, ev);
- break;
- case H_PREV:
- retval = HPREV(h, ev);
- break;
- case H_CURR:
- retval = HCURR(h, ev);
- break;
- case H_SET:
- retval = HSET(h, ev, va_arg(va, const int));
- break;
- case H_CLEAR:
- HCLEAR(h, ev);
- retval = 0;
- break;
- case H_LOAD:
- retval = history_load(h, va_arg(va, const char *));
- if (retval == -1)
- he_seterrev(ev, _HE_HIST_READ);
- break;
- case H_SAVE:
- retval = history_save(h, va_arg(va, const char *));
- 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;
- case H_NEXT_EVENT:
- retval = history_next_event(h, ev, va_arg(va, int));
- break;
- case H_PREV_STR:
- retval = history_prev_string(h, ev, va_arg(va, const char *));
- break;
- case H_NEXT_STR:
- retval = history_next_string(h, ev, va_arg(va, const char *));
- break;
- case H_FUNC:
- {
- History hf;
- hf.h_ref = va_arg(va, ptr_t);
- h->h_ent = -1;
- hf.h_first = va_arg(va, history_gfun_t);
- hf.h_next = va_arg(va, history_gfun_t);
- hf.h_last = va_arg(va, history_gfun_t);
- hf.h_prev = va_arg(va, history_gfun_t);
- hf.h_curr = va_arg(va, history_gfun_t);
- hf.h_set = va_arg(va, history_sfun_t);
- hf.h_clear = va_arg(va, history_vfun_t);
- hf.h_enter = va_arg(va, history_efun_t);
- hf.h_add = va_arg(va, history_efun_t);
- if ((retval = history_set_fun(h, &hf)) == -1)
- he_seterrev(ev, _HE_PARAM_MISSING);
- break;
- }
- case H_END:
- history_end(h);
- retval = 0;
- break;
- default:
- retval = -1;
- he_seterrev(ev, _HE_UNKNOWN);
- break;
- }
- va_end(va);
- return (retval);
- }
|