1*d0ef721eSBaptiste Daroussin /* $NetBSD: history.c,v 1.62 2018/09/13 09:03:40 kre Exp $ */ 2*d0ef721eSBaptiste Daroussin 3*d0ef721eSBaptiste Daroussin /*- 4*d0ef721eSBaptiste Daroussin * Copyright (c) 1992, 1993 5*d0ef721eSBaptiste Daroussin * The Regents of the University of California. All rights reserved. 6*d0ef721eSBaptiste Daroussin * 7*d0ef721eSBaptiste Daroussin * This code is derived from software contributed to Berkeley by 8*d0ef721eSBaptiste Daroussin * Christos Zoulas of Cornell University. 9*d0ef721eSBaptiste Daroussin * 10*d0ef721eSBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 11*d0ef721eSBaptiste Daroussin * modification, are permitted provided that the following conditions 12*d0ef721eSBaptiste Daroussin * are met: 13*d0ef721eSBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright 14*d0ef721eSBaptiste Daroussin * notice, this list of conditions and the following disclaimer. 15*d0ef721eSBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright 16*d0ef721eSBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 17*d0ef721eSBaptiste Daroussin * documentation and/or other materials provided with the distribution. 18*d0ef721eSBaptiste Daroussin * 3. Neither the name of the University nor the names of its contributors 19*d0ef721eSBaptiste Daroussin * may be used to endorse or promote products derived from this software 20*d0ef721eSBaptiste Daroussin * without specific prior written permission. 21*d0ef721eSBaptiste Daroussin * 22*d0ef721eSBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23*d0ef721eSBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24*d0ef721eSBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25*d0ef721eSBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26*d0ef721eSBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27*d0ef721eSBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28*d0ef721eSBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29*d0ef721eSBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30*d0ef721eSBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31*d0ef721eSBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32*d0ef721eSBaptiste Daroussin * SUCH DAMAGE. 33*d0ef721eSBaptiste Daroussin */ 34*d0ef721eSBaptiste Daroussin 35*d0ef721eSBaptiste Daroussin #include "config.h" 36*d0ef721eSBaptiste Daroussin #if !defined(lint) && !defined(SCCSID) 37*d0ef721eSBaptiste Daroussin #if 0 38*d0ef721eSBaptiste Daroussin static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93"; 39*d0ef721eSBaptiste Daroussin #else 40*d0ef721eSBaptiste Daroussin __RCSID("$NetBSD: history.c,v 1.62 2018/09/13 09:03:40 kre Exp $"); 41*d0ef721eSBaptiste Daroussin #endif 42*d0ef721eSBaptiste Daroussin #endif /* not lint && not SCCSID */ 43*d0ef721eSBaptiste Daroussin 44*d0ef721eSBaptiste Daroussin /* 45*d0ef721eSBaptiste Daroussin * hist.c: TYPE(History) access functions 46*d0ef721eSBaptiste Daroussin */ 47*d0ef721eSBaptiste Daroussin #include <sys/stat.h> 48*d0ef721eSBaptiste Daroussin #include <stdarg.h> 49*d0ef721eSBaptiste Daroussin #include <stdlib.h> 50*d0ef721eSBaptiste Daroussin #include <string.h> 51*d0ef721eSBaptiste Daroussin #include <vis.h> 52*d0ef721eSBaptiste Daroussin 53*d0ef721eSBaptiste Daroussin static const char hist_cookie[] = "_HiStOrY_V2_\n"; 54*d0ef721eSBaptiste Daroussin 55*d0ef721eSBaptiste Daroussin #include "histedit.h" 56*d0ef721eSBaptiste Daroussin 57*d0ef721eSBaptiste Daroussin 58*d0ef721eSBaptiste Daroussin #ifdef NARROWCHAR 59*d0ef721eSBaptiste Daroussin 60*d0ef721eSBaptiste Daroussin #define Char char 61*d0ef721eSBaptiste Daroussin #define FUN(prefix, rest) prefix ## _ ## rest 62*d0ef721eSBaptiste Daroussin #define FUNW(type) type 63*d0ef721eSBaptiste Daroussin #define TYPE(type) type 64*d0ef721eSBaptiste Daroussin #define STR(x) x 65*d0ef721eSBaptiste Daroussin 66*d0ef721eSBaptiste Daroussin #define Strlen(s) strlen(s) 67*d0ef721eSBaptiste Daroussin #define Strdup(s) strdup(s) 68*d0ef721eSBaptiste Daroussin #define Strcmp(d, s) strcmp(d, s) 69*d0ef721eSBaptiste Daroussin #define Strncmp(d, s, n) strncmp(d, s, n) 70*d0ef721eSBaptiste Daroussin #define Strncpy(d, s, n) strncpy(d, s, n) 71*d0ef721eSBaptiste Daroussin #define Strncat(d, s, n) strncat(d, s, n) 72*d0ef721eSBaptiste Daroussin #define ct_decode_string(s, b) (s) 73*d0ef721eSBaptiste Daroussin #define ct_encode_string(s, b) (s) 74*d0ef721eSBaptiste Daroussin 75*d0ef721eSBaptiste Daroussin #else 76*d0ef721eSBaptiste Daroussin #include "chartype.h" 77*d0ef721eSBaptiste Daroussin 78*d0ef721eSBaptiste Daroussin #define Char wchar_t 79*d0ef721eSBaptiste Daroussin #define FUN(prefix, rest) prefix ## _w ## rest 80*d0ef721eSBaptiste Daroussin #define FUNW(type) type ## _w 81*d0ef721eSBaptiste Daroussin #define TYPE(type) type ## W 82*d0ef721eSBaptiste Daroussin #define STR(x) L ## x 83*d0ef721eSBaptiste Daroussin 84*d0ef721eSBaptiste Daroussin #define Strlen(s) wcslen(s) 85*d0ef721eSBaptiste Daroussin #define Strdup(s) wcsdup(s) 86*d0ef721eSBaptiste Daroussin #define Strcmp(d, s) wcscmp(d, s) 87*d0ef721eSBaptiste Daroussin #define Strncmp(d, s, n) wcsncmp(d, s, n) 88*d0ef721eSBaptiste Daroussin #define Strncpy(d, s, n) wcsncpy(d, s, n) 89*d0ef721eSBaptiste Daroussin #define Strncat(d, s, n) wcsncat(d, s, n) 90*d0ef721eSBaptiste Daroussin 91*d0ef721eSBaptiste Daroussin #endif 92*d0ef721eSBaptiste Daroussin 93*d0ef721eSBaptiste Daroussin 94*d0ef721eSBaptiste Daroussin typedef int (*history_gfun_t)(void *, TYPE(HistEvent) *); 95*d0ef721eSBaptiste Daroussin typedef int (*history_efun_t)(void *, TYPE(HistEvent) *, const Char *); 96*d0ef721eSBaptiste Daroussin typedef void (*history_vfun_t)(void *, TYPE(HistEvent) *); 97*d0ef721eSBaptiste Daroussin typedef int (*history_sfun_t)(void *, TYPE(HistEvent) *, const int); 98*d0ef721eSBaptiste Daroussin 99*d0ef721eSBaptiste Daroussin struct TYPE(history) { 100*d0ef721eSBaptiste Daroussin void *h_ref; /* Argument for history fcns */ 101*d0ef721eSBaptiste Daroussin int h_ent; /* Last entry point for history */ 102*d0ef721eSBaptiste Daroussin history_gfun_t h_first; /* Get the first element */ 103*d0ef721eSBaptiste Daroussin history_gfun_t h_next; /* Get the next element */ 104*d0ef721eSBaptiste Daroussin history_gfun_t h_last; /* Get the last element */ 105*d0ef721eSBaptiste Daroussin history_gfun_t h_prev; /* Get the previous element */ 106*d0ef721eSBaptiste Daroussin history_gfun_t h_curr; /* Get the current element */ 107*d0ef721eSBaptiste Daroussin history_sfun_t h_set; /* Set the current element */ 108*d0ef721eSBaptiste Daroussin history_sfun_t h_del; /* Set the given element */ 109*d0ef721eSBaptiste Daroussin history_vfun_t h_clear; /* Clear the history list */ 110*d0ef721eSBaptiste Daroussin history_efun_t h_enter; /* Add an element */ 111*d0ef721eSBaptiste Daroussin history_efun_t h_add; /* Append to an element */ 112*d0ef721eSBaptiste Daroussin }; 113*d0ef721eSBaptiste Daroussin 114*d0ef721eSBaptiste Daroussin #define HNEXT(h, ev) (*(h)->h_next)((h)->h_ref, ev) 115*d0ef721eSBaptiste Daroussin #define HFIRST(h, ev) (*(h)->h_first)((h)->h_ref, ev) 116*d0ef721eSBaptiste Daroussin #define HPREV(h, ev) (*(h)->h_prev)((h)->h_ref, ev) 117*d0ef721eSBaptiste Daroussin #define HLAST(h, ev) (*(h)->h_last)((h)->h_ref, ev) 118*d0ef721eSBaptiste Daroussin #define HCURR(h, ev) (*(h)->h_curr)((h)->h_ref, ev) 119*d0ef721eSBaptiste Daroussin #define HSET(h, ev, n) (*(h)->h_set)((h)->h_ref, ev, n) 120*d0ef721eSBaptiste Daroussin #define HCLEAR(h, ev) (*(h)->h_clear)((h)->h_ref, ev) 121*d0ef721eSBaptiste Daroussin #define HENTER(h, ev, str) (*(h)->h_enter)((h)->h_ref, ev, str) 122*d0ef721eSBaptiste Daroussin #define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str) 123*d0ef721eSBaptiste Daroussin #define HDEL(h, ev, n) (*(h)->h_del)((h)->h_ref, ev, n) 124*d0ef721eSBaptiste Daroussin 125*d0ef721eSBaptiste Daroussin #define h_strdup(a) Strdup(a) 126*d0ef721eSBaptiste Daroussin #define h_malloc(a) malloc(a) 127*d0ef721eSBaptiste Daroussin #define h_realloc(a, b) realloc((a), (b)) 128*d0ef721eSBaptiste Daroussin #define h_free(a) free(a) 129*d0ef721eSBaptiste Daroussin 130*d0ef721eSBaptiste Daroussin typedef struct { 131*d0ef721eSBaptiste Daroussin int num; 132*d0ef721eSBaptiste Daroussin Char *str; 133*d0ef721eSBaptiste Daroussin } HistEventPrivate; 134*d0ef721eSBaptiste Daroussin 135*d0ef721eSBaptiste Daroussin 136*d0ef721eSBaptiste Daroussin static int history_setsize(TYPE(History) *, TYPE(HistEvent) *, int); 137*d0ef721eSBaptiste Daroussin static int history_getsize(TYPE(History) *, TYPE(HistEvent) *); 138*d0ef721eSBaptiste Daroussin static int history_setunique(TYPE(History) *, TYPE(HistEvent) *, int); 139*d0ef721eSBaptiste Daroussin static int history_getunique(TYPE(History) *, TYPE(HistEvent) *); 140*d0ef721eSBaptiste Daroussin static int history_set_fun(TYPE(History) *, TYPE(History) *); 141*d0ef721eSBaptiste Daroussin static int history_load(TYPE(History) *, const char *); 142*d0ef721eSBaptiste Daroussin static int history_save(TYPE(History) *, const char *); 143*d0ef721eSBaptiste Daroussin static int history_save_fp(TYPE(History) *, size_t, FILE *); 144*d0ef721eSBaptiste Daroussin static int history_prev_event(TYPE(History) *, TYPE(HistEvent) *, int); 145*d0ef721eSBaptiste Daroussin static int history_next_event(TYPE(History) *, TYPE(HistEvent) *, int); 146*d0ef721eSBaptiste Daroussin static int history_next_string(TYPE(History) *, TYPE(HistEvent) *, 147*d0ef721eSBaptiste Daroussin const Char *); 148*d0ef721eSBaptiste Daroussin static int history_prev_string(TYPE(History) *, TYPE(HistEvent) *, 149*d0ef721eSBaptiste Daroussin const Char *); 150*d0ef721eSBaptiste Daroussin 151*d0ef721eSBaptiste Daroussin 152*d0ef721eSBaptiste Daroussin /***********************************************************************/ 153*d0ef721eSBaptiste Daroussin 154*d0ef721eSBaptiste Daroussin /* 155*d0ef721eSBaptiste Daroussin * Builtin- history implementation 156*d0ef721eSBaptiste Daroussin */ 157*d0ef721eSBaptiste Daroussin typedef struct hentry_t { 158*d0ef721eSBaptiste Daroussin TYPE(HistEvent) ev; /* What we return */ 159*d0ef721eSBaptiste Daroussin void *data; /* data */ 160*d0ef721eSBaptiste Daroussin struct hentry_t *next; /* Next entry */ 161*d0ef721eSBaptiste Daroussin struct hentry_t *prev; /* Previous entry */ 162*d0ef721eSBaptiste Daroussin } hentry_t; 163*d0ef721eSBaptiste Daroussin 164*d0ef721eSBaptiste Daroussin typedef struct history_t { 165*d0ef721eSBaptiste Daroussin hentry_t list; /* Fake list header element */ 166*d0ef721eSBaptiste Daroussin hentry_t *cursor; /* Current element in the list */ 167*d0ef721eSBaptiste Daroussin int max; /* Maximum number of events */ 168*d0ef721eSBaptiste Daroussin int cur; /* Current number of events */ 169*d0ef721eSBaptiste Daroussin int eventid; /* For generation of unique event id */ 170*d0ef721eSBaptiste Daroussin int flags; /* TYPE(History) flags */ 171*d0ef721eSBaptiste Daroussin #define H_UNIQUE 1 /* Store only unique elements */ 172*d0ef721eSBaptiste Daroussin } history_t; 173*d0ef721eSBaptiste Daroussin 174*d0ef721eSBaptiste Daroussin static int history_def_next(void *, TYPE(HistEvent) *); 175*d0ef721eSBaptiste Daroussin static int history_def_first(void *, TYPE(HistEvent) *); 176*d0ef721eSBaptiste Daroussin static int history_def_prev(void *, TYPE(HistEvent) *); 177*d0ef721eSBaptiste Daroussin static int history_def_last(void *, TYPE(HistEvent) *); 178*d0ef721eSBaptiste Daroussin static int history_def_curr(void *, TYPE(HistEvent) *); 179*d0ef721eSBaptiste Daroussin static int history_def_set(void *, TYPE(HistEvent) *, const int); 180*d0ef721eSBaptiste Daroussin static void history_def_clear(void *, TYPE(HistEvent) *); 181*d0ef721eSBaptiste Daroussin static int history_def_enter(void *, TYPE(HistEvent) *, const Char *); 182*d0ef721eSBaptiste Daroussin static int history_def_add(void *, TYPE(HistEvent) *, const Char *); 183*d0ef721eSBaptiste Daroussin static int history_def_del(void *, TYPE(HistEvent) *, const int); 184*d0ef721eSBaptiste Daroussin 185*d0ef721eSBaptiste Daroussin static int history_def_init(void **, TYPE(HistEvent) *, int); 186*d0ef721eSBaptiste Daroussin static int history_def_insert(history_t *, TYPE(HistEvent) *, const Char *); 187*d0ef721eSBaptiste Daroussin static void history_def_delete(history_t *, TYPE(HistEvent) *, hentry_t *); 188*d0ef721eSBaptiste Daroussin 189*d0ef721eSBaptiste Daroussin static int history_deldata_nth(history_t *, TYPE(HistEvent) *, int, void **); 190*d0ef721eSBaptiste Daroussin static int history_set_nth(void *, TYPE(HistEvent) *, int); 191*d0ef721eSBaptiste Daroussin 192*d0ef721eSBaptiste Daroussin #define history_def_setsize(p, num)(void) (((history_t *)p)->max = (num)) 193*d0ef721eSBaptiste Daroussin #define history_def_getsize(p) (((history_t *)p)->cur) 194*d0ef721eSBaptiste Daroussin #define history_def_getunique(p) (((((history_t *)p)->flags) & H_UNIQUE) != 0) 195*d0ef721eSBaptiste Daroussin #define history_def_setunique(p, uni) \ 196*d0ef721eSBaptiste Daroussin if (uni) \ 197*d0ef721eSBaptiste Daroussin (((history_t *)p)->flags) |= H_UNIQUE; \ 198*d0ef721eSBaptiste Daroussin else \ 199*d0ef721eSBaptiste Daroussin (((history_t *)p)->flags) &= ~H_UNIQUE 200*d0ef721eSBaptiste Daroussin 201*d0ef721eSBaptiste Daroussin #define he_strerror(code) he_errlist[code] 202*d0ef721eSBaptiste Daroussin #define he_seterrev(evp, code) {\ 203*d0ef721eSBaptiste Daroussin evp->num = code;\ 204*d0ef721eSBaptiste Daroussin evp->str = he_strerror(code);\ 205*d0ef721eSBaptiste Daroussin } 206*d0ef721eSBaptiste Daroussin 207*d0ef721eSBaptiste Daroussin /* error messages */ 208*d0ef721eSBaptiste Daroussin static const Char *const he_errlist[] = { 209*d0ef721eSBaptiste Daroussin STR("OK"), 210*d0ef721eSBaptiste Daroussin STR("unknown error"), 211*d0ef721eSBaptiste Daroussin STR("malloc() failed"), 212*d0ef721eSBaptiste Daroussin STR("first event not found"), 213*d0ef721eSBaptiste Daroussin STR("last event not found"), 214*d0ef721eSBaptiste Daroussin STR("empty list"), 215*d0ef721eSBaptiste Daroussin STR("no next event"), 216*d0ef721eSBaptiste Daroussin STR("no previous event"), 217*d0ef721eSBaptiste Daroussin STR("current event is invalid"), 218*d0ef721eSBaptiste Daroussin STR("event not found"), 219*d0ef721eSBaptiste Daroussin STR("can't read history from file"), 220*d0ef721eSBaptiste Daroussin STR("can't write history"), 221*d0ef721eSBaptiste Daroussin STR("required parameter(s) not supplied"), 222*d0ef721eSBaptiste Daroussin STR("history size negative"), 223*d0ef721eSBaptiste Daroussin STR("function not allowed with other history-functions-set the default"), 224*d0ef721eSBaptiste Daroussin STR("bad parameters") 225*d0ef721eSBaptiste Daroussin }; 226*d0ef721eSBaptiste Daroussin /* error codes */ 227*d0ef721eSBaptiste Daroussin #define _HE_OK 0 228*d0ef721eSBaptiste Daroussin #define _HE_UNKNOWN 1 229*d0ef721eSBaptiste Daroussin #define _HE_MALLOC_FAILED 2 230*d0ef721eSBaptiste Daroussin #define _HE_FIRST_NOTFOUND 3 231*d0ef721eSBaptiste Daroussin #define _HE_LAST_NOTFOUND 4 232*d0ef721eSBaptiste Daroussin #define _HE_EMPTY_LIST 5 233*d0ef721eSBaptiste Daroussin #define _HE_END_REACHED 6 234*d0ef721eSBaptiste Daroussin #define _HE_START_REACHED 7 235*d0ef721eSBaptiste Daroussin #define _HE_CURR_INVALID 8 236*d0ef721eSBaptiste Daroussin #define _HE_NOT_FOUND 9 237*d0ef721eSBaptiste Daroussin #define _HE_HIST_READ 10 238*d0ef721eSBaptiste Daroussin #define _HE_HIST_WRITE 11 239*d0ef721eSBaptiste Daroussin #define _HE_PARAM_MISSING 12 240*d0ef721eSBaptiste Daroussin #define _HE_SIZE_NEGATIVE 13 241*d0ef721eSBaptiste Daroussin #define _HE_NOT_ALLOWED 14 242*d0ef721eSBaptiste Daroussin #define _HE_BAD_PARAM 15 243*d0ef721eSBaptiste Daroussin 244*d0ef721eSBaptiste Daroussin /* history_def_first(): 245*d0ef721eSBaptiste Daroussin * Default function to return the first event in the history. 246*d0ef721eSBaptiste Daroussin */ 247*d0ef721eSBaptiste Daroussin static int 248*d0ef721eSBaptiste Daroussin history_def_first(void *p, TYPE(HistEvent) *ev) 249*d0ef721eSBaptiste Daroussin { 250*d0ef721eSBaptiste Daroussin history_t *h = (history_t *) p; 251*d0ef721eSBaptiste Daroussin 252*d0ef721eSBaptiste Daroussin h->cursor = h->list.next; 253*d0ef721eSBaptiste Daroussin if (h->cursor != &h->list) 254*d0ef721eSBaptiste Daroussin *ev = h->cursor->ev; 255*d0ef721eSBaptiste Daroussin else { 256*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_FIRST_NOTFOUND); 257*d0ef721eSBaptiste Daroussin return -1; 258*d0ef721eSBaptiste Daroussin } 259*d0ef721eSBaptiste Daroussin 260*d0ef721eSBaptiste Daroussin return 0; 261*d0ef721eSBaptiste Daroussin } 262*d0ef721eSBaptiste Daroussin 263*d0ef721eSBaptiste Daroussin 264*d0ef721eSBaptiste Daroussin /* history_def_last(): 265*d0ef721eSBaptiste Daroussin * Default function to return the last event in the history. 266*d0ef721eSBaptiste Daroussin */ 267*d0ef721eSBaptiste Daroussin static int 268*d0ef721eSBaptiste Daroussin history_def_last(void *p, TYPE(HistEvent) *ev) 269*d0ef721eSBaptiste Daroussin { 270*d0ef721eSBaptiste Daroussin history_t *h = (history_t *) p; 271*d0ef721eSBaptiste Daroussin 272*d0ef721eSBaptiste Daroussin h->cursor = h->list.prev; 273*d0ef721eSBaptiste Daroussin if (h->cursor != &h->list) 274*d0ef721eSBaptiste Daroussin *ev = h->cursor->ev; 275*d0ef721eSBaptiste Daroussin else { 276*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_LAST_NOTFOUND); 277*d0ef721eSBaptiste Daroussin return -1; 278*d0ef721eSBaptiste Daroussin } 279*d0ef721eSBaptiste Daroussin 280*d0ef721eSBaptiste Daroussin return 0; 281*d0ef721eSBaptiste Daroussin } 282*d0ef721eSBaptiste Daroussin 283*d0ef721eSBaptiste Daroussin 284*d0ef721eSBaptiste Daroussin /* history_def_next(): 285*d0ef721eSBaptiste Daroussin * Default function to return the next event in the history. 286*d0ef721eSBaptiste Daroussin */ 287*d0ef721eSBaptiste Daroussin static int 288*d0ef721eSBaptiste Daroussin history_def_next(void *p, TYPE(HistEvent) *ev) 289*d0ef721eSBaptiste Daroussin { 290*d0ef721eSBaptiste Daroussin history_t *h = (history_t *) p; 291*d0ef721eSBaptiste Daroussin 292*d0ef721eSBaptiste Daroussin if (h->cursor == &h->list) { 293*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_EMPTY_LIST); 294*d0ef721eSBaptiste Daroussin return -1; 295*d0ef721eSBaptiste Daroussin } 296*d0ef721eSBaptiste Daroussin 297*d0ef721eSBaptiste Daroussin if (h->cursor->next == &h->list) { 298*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_END_REACHED); 299*d0ef721eSBaptiste Daroussin return -1; 300*d0ef721eSBaptiste Daroussin } 301*d0ef721eSBaptiste Daroussin 302*d0ef721eSBaptiste Daroussin h->cursor = h->cursor->next; 303*d0ef721eSBaptiste Daroussin *ev = h->cursor->ev; 304*d0ef721eSBaptiste Daroussin 305*d0ef721eSBaptiste Daroussin return 0; 306*d0ef721eSBaptiste Daroussin } 307*d0ef721eSBaptiste Daroussin 308*d0ef721eSBaptiste Daroussin 309*d0ef721eSBaptiste Daroussin /* history_def_prev(): 310*d0ef721eSBaptiste Daroussin * Default function to return the previous event in the history. 311*d0ef721eSBaptiste Daroussin */ 312*d0ef721eSBaptiste Daroussin static int 313*d0ef721eSBaptiste Daroussin history_def_prev(void *p, TYPE(HistEvent) *ev) 314*d0ef721eSBaptiste Daroussin { 315*d0ef721eSBaptiste Daroussin history_t *h = (history_t *) p; 316*d0ef721eSBaptiste Daroussin 317*d0ef721eSBaptiste Daroussin if (h->cursor == &h->list) { 318*d0ef721eSBaptiste Daroussin he_seterrev(ev, 319*d0ef721eSBaptiste Daroussin (h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST); 320*d0ef721eSBaptiste Daroussin return -1; 321*d0ef721eSBaptiste Daroussin } 322*d0ef721eSBaptiste Daroussin 323*d0ef721eSBaptiste Daroussin if (h->cursor->prev == &h->list) { 324*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_START_REACHED); 325*d0ef721eSBaptiste Daroussin return -1; 326*d0ef721eSBaptiste Daroussin } 327*d0ef721eSBaptiste Daroussin 328*d0ef721eSBaptiste Daroussin h->cursor = h->cursor->prev; 329*d0ef721eSBaptiste Daroussin *ev = h->cursor->ev; 330*d0ef721eSBaptiste Daroussin 331*d0ef721eSBaptiste Daroussin return 0; 332*d0ef721eSBaptiste Daroussin } 333*d0ef721eSBaptiste Daroussin 334*d0ef721eSBaptiste Daroussin 335*d0ef721eSBaptiste Daroussin /* history_def_curr(): 336*d0ef721eSBaptiste Daroussin * Default function to return the current event in the history. 337*d0ef721eSBaptiste Daroussin */ 338*d0ef721eSBaptiste Daroussin static int 339*d0ef721eSBaptiste Daroussin history_def_curr(void *p, TYPE(HistEvent) *ev) 340*d0ef721eSBaptiste Daroussin { 341*d0ef721eSBaptiste Daroussin history_t *h = (history_t *) p; 342*d0ef721eSBaptiste Daroussin 343*d0ef721eSBaptiste Daroussin if (h->cursor != &h->list) 344*d0ef721eSBaptiste Daroussin *ev = h->cursor->ev; 345*d0ef721eSBaptiste Daroussin else { 346*d0ef721eSBaptiste Daroussin he_seterrev(ev, 347*d0ef721eSBaptiste Daroussin (h->cur > 0) ? _HE_CURR_INVALID : _HE_EMPTY_LIST); 348*d0ef721eSBaptiste Daroussin return -1; 349*d0ef721eSBaptiste Daroussin } 350*d0ef721eSBaptiste Daroussin 351*d0ef721eSBaptiste Daroussin return 0; 352*d0ef721eSBaptiste Daroussin } 353*d0ef721eSBaptiste Daroussin 354*d0ef721eSBaptiste Daroussin 355*d0ef721eSBaptiste Daroussin /* history_def_set(): 356*d0ef721eSBaptiste Daroussin * Default function to set the current event in the history to the 357*d0ef721eSBaptiste Daroussin * given one. 358*d0ef721eSBaptiste Daroussin */ 359*d0ef721eSBaptiste Daroussin static int 360*d0ef721eSBaptiste Daroussin history_def_set(void *p, TYPE(HistEvent) *ev, const int n) 361*d0ef721eSBaptiste Daroussin { 362*d0ef721eSBaptiste Daroussin history_t *h = (history_t *) p; 363*d0ef721eSBaptiste Daroussin 364*d0ef721eSBaptiste Daroussin if (h->cur == 0) { 365*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_EMPTY_LIST); 366*d0ef721eSBaptiste Daroussin return -1; 367*d0ef721eSBaptiste Daroussin } 368*d0ef721eSBaptiste Daroussin if (h->cursor == &h->list || h->cursor->ev.num != n) { 369*d0ef721eSBaptiste Daroussin for (h->cursor = h->list.next; h->cursor != &h->list; 370*d0ef721eSBaptiste Daroussin h->cursor = h->cursor->next) 371*d0ef721eSBaptiste Daroussin if (h->cursor->ev.num == n) 372*d0ef721eSBaptiste Daroussin break; 373*d0ef721eSBaptiste Daroussin } 374*d0ef721eSBaptiste Daroussin if (h->cursor == &h->list) { 375*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_NOT_FOUND); 376*d0ef721eSBaptiste Daroussin return -1; 377*d0ef721eSBaptiste Daroussin } 378*d0ef721eSBaptiste Daroussin return 0; 379*d0ef721eSBaptiste Daroussin } 380*d0ef721eSBaptiste Daroussin 381*d0ef721eSBaptiste Daroussin 382*d0ef721eSBaptiste Daroussin /* history_set_nth(): 383*d0ef721eSBaptiste Daroussin * Default function to set the current event in the history to the 384*d0ef721eSBaptiste Daroussin * n-th one. 385*d0ef721eSBaptiste Daroussin */ 386*d0ef721eSBaptiste Daroussin static int 387*d0ef721eSBaptiste Daroussin history_set_nth(void *p, TYPE(HistEvent) *ev, int n) 388*d0ef721eSBaptiste Daroussin { 389*d0ef721eSBaptiste Daroussin history_t *h = (history_t *) p; 390*d0ef721eSBaptiste Daroussin 391*d0ef721eSBaptiste Daroussin if (h->cur == 0) { 392*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_EMPTY_LIST); 393*d0ef721eSBaptiste Daroussin return -1; 394*d0ef721eSBaptiste Daroussin } 395*d0ef721eSBaptiste Daroussin for (h->cursor = h->list.prev; h->cursor != &h->list; 396*d0ef721eSBaptiste Daroussin h->cursor = h->cursor->prev) 397*d0ef721eSBaptiste Daroussin if (n-- <= 0) 398*d0ef721eSBaptiste Daroussin break; 399*d0ef721eSBaptiste Daroussin if (h->cursor == &h->list) { 400*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_NOT_FOUND); 401*d0ef721eSBaptiste Daroussin return -1; 402*d0ef721eSBaptiste Daroussin } 403*d0ef721eSBaptiste Daroussin return 0; 404*d0ef721eSBaptiste Daroussin } 405*d0ef721eSBaptiste Daroussin 406*d0ef721eSBaptiste Daroussin 407*d0ef721eSBaptiste Daroussin /* history_def_add(): 408*d0ef721eSBaptiste Daroussin * Append string to element 409*d0ef721eSBaptiste Daroussin */ 410*d0ef721eSBaptiste Daroussin static int 411*d0ef721eSBaptiste Daroussin history_def_add(void *p, TYPE(HistEvent) *ev, const Char *str) 412*d0ef721eSBaptiste Daroussin { 413*d0ef721eSBaptiste Daroussin history_t *h = (history_t *) p; 414*d0ef721eSBaptiste Daroussin size_t len; 415*d0ef721eSBaptiste Daroussin Char *s; 416*d0ef721eSBaptiste Daroussin HistEventPrivate *evp = (void *)&h->cursor->ev; 417*d0ef721eSBaptiste Daroussin 418*d0ef721eSBaptiste Daroussin if (h->cursor == &h->list) 419*d0ef721eSBaptiste Daroussin return history_def_enter(p, ev, str); 420*d0ef721eSBaptiste Daroussin len = Strlen(evp->str) + Strlen(str) + 1; 421*d0ef721eSBaptiste Daroussin s = h_malloc(len * sizeof(*s)); 422*d0ef721eSBaptiste Daroussin if (s == NULL) { 423*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_MALLOC_FAILED); 424*d0ef721eSBaptiste Daroussin return -1; 425*d0ef721eSBaptiste Daroussin } 426*d0ef721eSBaptiste Daroussin (void) Strncpy(s, h->cursor->ev.str, len); 427*d0ef721eSBaptiste Daroussin s[len - 1] = '\0'; 428*d0ef721eSBaptiste Daroussin (void) Strncat(s, str, len - Strlen(s) - 1); 429*d0ef721eSBaptiste Daroussin h_free(evp->str); 430*d0ef721eSBaptiste Daroussin evp->str = s; 431*d0ef721eSBaptiste Daroussin *ev = h->cursor->ev; 432*d0ef721eSBaptiste Daroussin return 0; 433*d0ef721eSBaptiste Daroussin } 434*d0ef721eSBaptiste Daroussin 435*d0ef721eSBaptiste Daroussin 436*d0ef721eSBaptiste Daroussin static int 437*d0ef721eSBaptiste Daroussin history_deldata_nth(history_t *h, TYPE(HistEvent) *ev, 438*d0ef721eSBaptiste Daroussin int num, void **data) 439*d0ef721eSBaptiste Daroussin { 440*d0ef721eSBaptiste Daroussin if (history_set_nth(h, ev, num) != 0) 441*d0ef721eSBaptiste Daroussin return -1; 442*d0ef721eSBaptiste Daroussin /* magic value to skip delete (just set to n-th history) */ 443*d0ef721eSBaptiste Daroussin if (data == (void **)-1) 444*d0ef721eSBaptiste Daroussin return 0; 445*d0ef721eSBaptiste Daroussin ev->str = Strdup(h->cursor->ev.str); 446*d0ef721eSBaptiste Daroussin ev->num = h->cursor->ev.num; 447*d0ef721eSBaptiste Daroussin if (data) 448*d0ef721eSBaptiste Daroussin *data = h->cursor->data; 449*d0ef721eSBaptiste Daroussin history_def_delete(h, ev, h->cursor); 450*d0ef721eSBaptiste Daroussin return 0; 451*d0ef721eSBaptiste Daroussin } 452*d0ef721eSBaptiste Daroussin 453*d0ef721eSBaptiste Daroussin 454*d0ef721eSBaptiste Daroussin /* history_def_del(): 455*d0ef721eSBaptiste Daroussin * Delete element hp of the h list 456*d0ef721eSBaptiste Daroussin */ 457*d0ef721eSBaptiste Daroussin /* ARGSUSED */ 458*d0ef721eSBaptiste Daroussin static int 459*d0ef721eSBaptiste Daroussin history_def_del(void *p, TYPE(HistEvent) *ev __attribute__((__unused__)), 460*d0ef721eSBaptiste Daroussin const int num) 461*d0ef721eSBaptiste Daroussin { 462*d0ef721eSBaptiste Daroussin history_t *h = (history_t *) p; 463*d0ef721eSBaptiste Daroussin if (history_def_set(h, ev, num) != 0) 464*d0ef721eSBaptiste Daroussin return -1; 465*d0ef721eSBaptiste Daroussin ev->str = Strdup(h->cursor->ev.str); 466*d0ef721eSBaptiste Daroussin ev->num = h->cursor->ev.num; 467*d0ef721eSBaptiste Daroussin history_def_delete(h, ev, h->cursor); 468*d0ef721eSBaptiste Daroussin return 0; 469*d0ef721eSBaptiste Daroussin } 470*d0ef721eSBaptiste Daroussin 471*d0ef721eSBaptiste Daroussin 472*d0ef721eSBaptiste Daroussin /* history_def_delete(): 473*d0ef721eSBaptiste Daroussin * Delete element hp of the h list 474*d0ef721eSBaptiste Daroussin */ 475*d0ef721eSBaptiste Daroussin /* ARGSUSED */ 476*d0ef721eSBaptiste Daroussin static void 477*d0ef721eSBaptiste Daroussin history_def_delete(history_t *h, 478*d0ef721eSBaptiste Daroussin TYPE(HistEvent) *ev __attribute__((__unused__)), hentry_t *hp) 479*d0ef721eSBaptiste Daroussin { 480*d0ef721eSBaptiste Daroussin HistEventPrivate *evp = (void *)&hp->ev; 481*d0ef721eSBaptiste Daroussin if (hp == &h->list) 482*d0ef721eSBaptiste Daroussin abort(); 483*d0ef721eSBaptiste Daroussin if (h->cursor == hp) { 484*d0ef721eSBaptiste Daroussin h->cursor = hp->prev; 485*d0ef721eSBaptiste Daroussin if (h->cursor == &h->list) 486*d0ef721eSBaptiste Daroussin h->cursor = hp->next; 487*d0ef721eSBaptiste Daroussin } 488*d0ef721eSBaptiste Daroussin hp->prev->next = hp->next; 489*d0ef721eSBaptiste Daroussin hp->next->prev = hp->prev; 490*d0ef721eSBaptiste Daroussin h_free(evp->str); 491*d0ef721eSBaptiste Daroussin h_free(hp); 492*d0ef721eSBaptiste Daroussin h->cur--; 493*d0ef721eSBaptiste Daroussin } 494*d0ef721eSBaptiste Daroussin 495*d0ef721eSBaptiste Daroussin 496*d0ef721eSBaptiste Daroussin /* history_def_insert(): 497*d0ef721eSBaptiste Daroussin * Insert element with string str in the h list 498*d0ef721eSBaptiste Daroussin */ 499*d0ef721eSBaptiste Daroussin static int 500*d0ef721eSBaptiste Daroussin history_def_insert(history_t *h, TYPE(HistEvent) *ev, const Char *str) 501*d0ef721eSBaptiste Daroussin { 502*d0ef721eSBaptiste Daroussin hentry_t *c; 503*d0ef721eSBaptiste Daroussin 504*d0ef721eSBaptiste Daroussin c = h_malloc(sizeof(*c)); 505*d0ef721eSBaptiste Daroussin if (c == NULL) 506*d0ef721eSBaptiste Daroussin goto oomem; 507*d0ef721eSBaptiste Daroussin if ((c->ev.str = h_strdup(str)) == NULL) { 508*d0ef721eSBaptiste Daroussin h_free(c); 509*d0ef721eSBaptiste Daroussin goto oomem; 510*d0ef721eSBaptiste Daroussin } 511*d0ef721eSBaptiste Daroussin c->data = NULL; 512*d0ef721eSBaptiste Daroussin c->ev.num = ++h->eventid; 513*d0ef721eSBaptiste Daroussin c->next = h->list.next; 514*d0ef721eSBaptiste Daroussin c->prev = &h->list; 515*d0ef721eSBaptiste Daroussin h->list.next->prev = c; 516*d0ef721eSBaptiste Daroussin h->list.next = c; 517*d0ef721eSBaptiste Daroussin h->cur++; 518*d0ef721eSBaptiste Daroussin h->cursor = c; 519*d0ef721eSBaptiste Daroussin 520*d0ef721eSBaptiste Daroussin *ev = c->ev; 521*d0ef721eSBaptiste Daroussin return 0; 522*d0ef721eSBaptiste Daroussin oomem: 523*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_MALLOC_FAILED); 524*d0ef721eSBaptiste Daroussin return -1; 525*d0ef721eSBaptiste Daroussin } 526*d0ef721eSBaptiste Daroussin 527*d0ef721eSBaptiste Daroussin 528*d0ef721eSBaptiste Daroussin /* history_def_enter(): 529*d0ef721eSBaptiste Daroussin * Default function to enter an item in the history 530*d0ef721eSBaptiste Daroussin */ 531*d0ef721eSBaptiste Daroussin static int 532*d0ef721eSBaptiste Daroussin history_def_enter(void *p, TYPE(HistEvent) *ev, const Char *str) 533*d0ef721eSBaptiste Daroussin { 534*d0ef721eSBaptiste Daroussin history_t *h = (history_t *) p; 535*d0ef721eSBaptiste Daroussin 536*d0ef721eSBaptiste Daroussin if ((h->flags & H_UNIQUE) != 0 && h->list.next != &h->list && 537*d0ef721eSBaptiste Daroussin Strcmp(h->list.next->ev.str, str) == 0) 538*d0ef721eSBaptiste Daroussin return 0; 539*d0ef721eSBaptiste Daroussin 540*d0ef721eSBaptiste Daroussin if (history_def_insert(h, ev, str) == -1) 541*d0ef721eSBaptiste Daroussin return -1; /* error, keep error message */ 542*d0ef721eSBaptiste Daroussin 543*d0ef721eSBaptiste Daroussin /* 544*d0ef721eSBaptiste Daroussin * Always keep at least one entry. 545*d0ef721eSBaptiste Daroussin * This way we don't have to check for the empty list. 546*d0ef721eSBaptiste Daroussin */ 547*d0ef721eSBaptiste Daroussin while (h->cur > h->max && h->cur > 0) 548*d0ef721eSBaptiste Daroussin history_def_delete(h, ev, h->list.prev); 549*d0ef721eSBaptiste Daroussin 550*d0ef721eSBaptiste Daroussin return 1; 551*d0ef721eSBaptiste Daroussin } 552*d0ef721eSBaptiste Daroussin 553*d0ef721eSBaptiste Daroussin 554*d0ef721eSBaptiste Daroussin /* history_def_init(): 555*d0ef721eSBaptiste Daroussin * Default history initialization function 556*d0ef721eSBaptiste Daroussin */ 557*d0ef721eSBaptiste Daroussin /* ARGSUSED */ 558*d0ef721eSBaptiste Daroussin static int 559*d0ef721eSBaptiste Daroussin history_def_init(void **p, TYPE(HistEvent) *ev __attribute__((__unused__)), int n) 560*d0ef721eSBaptiste Daroussin { 561*d0ef721eSBaptiste Daroussin history_t *h = (history_t *) h_malloc(sizeof(*h)); 562*d0ef721eSBaptiste Daroussin if (h == NULL) 563*d0ef721eSBaptiste Daroussin return -1; 564*d0ef721eSBaptiste Daroussin 565*d0ef721eSBaptiste Daroussin if (n <= 0) 566*d0ef721eSBaptiste Daroussin n = 0; 567*d0ef721eSBaptiste Daroussin h->eventid = 0; 568*d0ef721eSBaptiste Daroussin h->cur = 0; 569*d0ef721eSBaptiste Daroussin h->max = n; 570*d0ef721eSBaptiste Daroussin h->list.next = h->list.prev = &h->list; 571*d0ef721eSBaptiste Daroussin h->list.ev.str = NULL; 572*d0ef721eSBaptiste Daroussin h->list.ev.num = 0; 573*d0ef721eSBaptiste Daroussin h->cursor = &h->list; 574*d0ef721eSBaptiste Daroussin h->flags = 0; 575*d0ef721eSBaptiste Daroussin *p = h; 576*d0ef721eSBaptiste Daroussin return 0; 577*d0ef721eSBaptiste Daroussin } 578*d0ef721eSBaptiste Daroussin 579*d0ef721eSBaptiste Daroussin 580*d0ef721eSBaptiste Daroussin /* history_def_clear(): 581*d0ef721eSBaptiste Daroussin * Default history cleanup function 582*d0ef721eSBaptiste Daroussin */ 583*d0ef721eSBaptiste Daroussin static void 584*d0ef721eSBaptiste Daroussin history_def_clear(void *p, TYPE(HistEvent) *ev) 585*d0ef721eSBaptiste Daroussin { 586*d0ef721eSBaptiste Daroussin history_t *h = (history_t *) p; 587*d0ef721eSBaptiste Daroussin 588*d0ef721eSBaptiste Daroussin while (h->list.prev != &h->list) 589*d0ef721eSBaptiste Daroussin history_def_delete(h, ev, h->list.prev); 590*d0ef721eSBaptiste Daroussin h->cursor = &h->list; 591*d0ef721eSBaptiste Daroussin h->eventid = 0; 592*d0ef721eSBaptiste Daroussin h->cur = 0; 593*d0ef721eSBaptiste Daroussin } 594*d0ef721eSBaptiste Daroussin 595*d0ef721eSBaptiste Daroussin 596*d0ef721eSBaptiste Daroussin 597*d0ef721eSBaptiste Daroussin 598*d0ef721eSBaptiste Daroussin /************************************************************************/ 599*d0ef721eSBaptiste Daroussin 600*d0ef721eSBaptiste Daroussin /* history_init(): 601*d0ef721eSBaptiste Daroussin * Initialization function. 602*d0ef721eSBaptiste Daroussin */ 603*d0ef721eSBaptiste Daroussin TYPE(History) * 604*d0ef721eSBaptiste Daroussin FUN(history,init)(void) 605*d0ef721eSBaptiste Daroussin { 606*d0ef721eSBaptiste Daroussin TYPE(HistEvent) ev; 607*d0ef721eSBaptiste Daroussin TYPE(History) *h = (TYPE(History) *) h_malloc(sizeof(*h)); 608*d0ef721eSBaptiste Daroussin if (h == NULL) 609*d0ef721eSBaptiste Daroussin return NULL; 610*d0ef721eSBaptiste Daroussin 611*d0ef721eSBaptiste Daroussin if (history_def_init(&h->h_ref, &ev, 0) == -1) { 612*d0ef721eSBaptiste Daroussin h_free(h); 613*d0ef721eSBaptiste Daroussin return NULL; 614*d0ef721eSBaptiste Daroussin } 615*d0ef721eSBaptiste Daroussin h->h_ent = -1; 616*d0ef721eSBaptiste Daroussin h->h_next = history_def_next; 617*d0ef721eSBaptiste Daroussin h->h_first = history_def_first; 618*d0ef721eSBaptiste Daroussin h->h_last = history_def_last; 619*d0ef721eSBaptiste Daroussin h->h_prev = history_def_prev; 620*d0ef721eSBaptiste Daroussin h->h_curr = history_def_curr; 621*d0ef721eSBaptiste Daroussin h->h_set = history_def_set; 622*d0ef721eSBaptiste Daroussin h->h_clear = history_def_clear; 623*d0ef721eSBaptiste Daroussin h->h_enter = history_def_enter; 624*d0ef721eSBaptiste Daroussin h->h_add = history_def_add; 625*d0ef721eSBaptiste Daroussin h->h_del = history_def_del; 626*d0ef721eSBaptiste Daroussin 627*d0ef721eSBaptiste Daroussin return h; 628*d0ef721eSBaptiste Daroussin } 629*d0ef721eSBaptiste Daroussin 630*d0ef721eSBaptiste Daroussin 631*d0ef721eSBaptiste Daroussin /* history_end(): 632*d0ef721eSBaptiste Daroussin * clean up history; 633*d0ef721eSBaptiste Daroussin */ 634*d0ef721eSBaptiste Daroussin void 635*d0ef721eSBaptiste Daroussin FUN(history,end)(TYPE(History) *h) 636*d0ef721eSBaptiste Daroussin { 637*d0ef721eSBaptiste Daroussin TYPE(HistEvent) ev; 638*d0ef721eSBaptiste Daroussin 639*d0ef721eSBaptiste Daroussin if (h->h_next == history_def_next) 640*d0ef721eSBaptiste Daroussin history_def_clear(h->h_ref, &ev); 641*d0ef721eSBaptiste Daroussin h_free(h->h_ref); 642*d0ef721eSBaptiste Daroussin h_free(h); 643*d0ef721eSBaptiste Daroussin } 644*d0ef721eSBaptiste Daroussin 645*d0ef721eSBaptiste Daroussin 646*d0ef721eSBaptiste Daroussin 647*d0ef721eSBaptiste Daroussin /* history_setsize(): 648*d0ef721eSBaptiste Daroussin * Set history number of events 649*d0ef721eSBaptiste Daroussin */ 650*d0ef721eSBaptiste Daroussin static int 651*d0ef721eSBaptiste Daroussin history_setsize(TYPE(History) *h, TYPE(HistEvent) *ev, int num) 652*d0ef721eSBaptiste Daroussin { 653*d0ef721eSBaptiste Daroussin 654*d0ef721eSBaptiste Daroussin if (h->h_next != history_def_next) { 655*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_NOT_ALLOWED); 656*d0ef721eSBaptiste Daroussin return -1; 657*d0ef721eSBaptiste Daroussin } 658*d0ef721eSBaptiste Daroussin if (num < 0) { 659*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_BAD_PARAM); 660*d0ef721eSBaptiste Daroussin return -1; 661*d0ef721eSBaptiste Daroussin } 662*d0ef721eSBaptiste Daroussin history_def_setsize(h->h_ref, num); 663*d0ef721eSBaptiste Daroussin return 0; 664*d0ef721eSBaptiste Daroussin } 665*d0ef721eSBaptiste Daroussin 666*d0ef721eSBaptiste Daroussin 667*d0ef721eSBaptiste Daroussin /* history_getsize(): 668*d0ef721eSBaptiste Daroussin * Get number of events currently in history 669*d0ef721eSBaptiste Daroussin */ 670*d0ef721eSBaptiste Daroussin static int 671*d0ef721eSBaptiste Daroussin history_getsize(TYPE(History) *h, TYPE(HistEvent) *ev) 672*d0ef721eSBaptiste Daroussin { 673*d0ef721eSBaptiste Daroussin if (h->h_next != history_def_next) { 674*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_NOT_ALLOWED); 675*d0ef721eSBaptiste Daroussin return -1; 676*d0ef721eSBaptiste Daroussin } 677*d0ef721eSBaptiste Daroussin ev->num = history_def_getsize(h->h_ref); 678*d0ef721eSBaptiste Daroussin if (ev->num < -1) { 679*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_SIZE_NEGATIVE); 680*d0ef721eSBaptiste Daroussin return -1; 681*d0ef721eSBaptiste Daroussin } 682*d0ef721eSBaptiste Daroussin return 0; 683*d0ef721eSBaptiste Daroussin } 684*d0ef721eSBaptiste Daroussin 685*d0ef721eSBaptiste Daroussin 686*d0ef721eSBaptiste Daroussin /* history_setunique(): 687*d0ef721eSBaptiste Daroussin * Set if adjacent equal events should not be entered in history. 688*d0ef721eSBaptiste Daroussin */ 689*d0ef721eSBaptiste Daroussin static int 690*d0ef721eSBaptiste Daroussin history_setunique(TYPE(History) *h, TYPE(HistEvent) *ev, int uni) 691*d0ef721eSBaptiste Daroussin { 692*d0ef721eSBaptiste Daroussin 693*d0ef721eSBaptiste Daroussin if (h->h_next != history_def_next) { 694*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_NOT_ALLOWED); 695*d0ef721eSBaptiste Daroussin return -1; 696*d0ef721eSBaptiste Daroussin } 697*d0ef721eSBaptiste Daroussin history_def_setunique(h->h_ref, uni); 698*d0ef721eSBaptiste Daroussin return 0; 699*d0ef721eSBaptiste Daroussin } 700*d0ef721eSBaptiste Daroussin 701*d0ef721eSBaptiste Daroussin 702*d0ef721eSBaptiste Daroussin /* history_getunique(): 703*d0ef721eSBaptiste Daroussin * Get if adjacent equal events should not be entered in history. 704*d0ef721eSBaptiste Daroussin */ 705*d0ef721eSBaptiste Daroussin static int 706*d0ef721eSBaptiste Daroussin history_getunique(TYPE(History) *h, TYPE(HistEvent) *ev) 707*d0ef721eSBaptiste Daroussin { 708*d0ef721eSBaptiste Daroussin if (h->h_next != history_def_next) { 709*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_NOT_ALLOWED); 710*d0ef721eSBaptiste Daroussin return -1; 711*d0ef721eSBaptiste Daroussin } 712*d0ef721eSBaptiste Daroussin ev->num = history_def_getunique(h->h_ref); 713*d0ef721eSBaptiste Daroussin return 0; 714*d0ef721eSBaptiste Daroussin } 715*d0ef721eSBaptiste Daroussin 716*d0ef721eSBaptiste Daroussin 717*d0ef721eSBaptiste Daroussin /* history_set_fun(): 718*d0ef721eSBaptiste Daroussin * Set history functions 719*d0ef721eSBaptiste Daroussin */ 720*d0ef721eSBaptiste Daroussin static int 721*d0ef721eSBaptiste Daroussin history_set_fun(TYPE(History) *h, TYPE(History) *nh) 722*d0ef721eSBaptiste Daroussin { 723*d0ef721eSBaptiste Daroussin TYPE(HistEvent) ev; 724*d0ef721eSBaptiste Daroussin 725*d0ef721eSBaptiste Daroussin if (nh->h_first == NULL || nh->h_next == NULL || nh->h_last == NULL || 726*d0ef721eSBaptiste Daroussin nh->h_prev == NULL || nh->h_curr == NULL || nh->h_set == NULL || 727*d0ef721eSBaptiste Daroussin nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL || 728*d0ef721eSBaptiste Daroussin nh->h_del == NULL || nh->h_ref == NULL) { 729*d0ef721eSBaptiste Daroussin if (h->h_next != history_def_next) { 730*d0ef721eSBaptiste Daroussin if (history_def_init(&h->h_ref, &ev, 0) == -1) 731*d0ef721eSBaptiste Daroussin return -1; 732*d0ef721eSBaptiste Daroussin h->h_first = history_def_first; 733*d0ef721eSBaptiste Daroussin h->h_next = history_def_next; 734*d0ef721eSBaptiste Daroussin h->h_last = history_def_last; 735*d0ef721eSBaptiste Daroussin h->h_prev = history_def_prev; 736*d0ef721eSBaptiste Daroussin h->h_curr = history_def_curr; 737*d0ef721eSBaptiste Daroussin h->h_set = history_def_set; 738*d0ef721eSBaptiste Daroussin h->h_clear = history_def_clear; 739*d0ef721eSBaptiste Daroussin h->h_enter = history_def_enter; 740*d0ef721eSBaptiste Daroussin h->h_add = history_def_add; 741*d0ef721eSBaptiste Daroussin h->h_del = history_def_del; 742*d0ef721eSBaptiste Daroussin } 743*d0ef721eSBaptiste Daroussin return -1; 744*d0ef721eSBaptiste Daroussin } 745*d0ef721eSBaptiste Daroussin if (h->h_next == history_def_next) 746*d0ef721eSBaptiste Daroussin history_def_clear(h->h_ref, &ev); 747*d0ef721eSBaptiste Daroussin 748*d0ef721eSBaptiste Daroussin h->h_ent = -1; 749*d0ef721eSBaptiste Daroussin h->h_first = nh->h_first; 750*d0ef721eSBaptiste Daroussin h->h_next = nh->h_next; 751*d0ef721eSBaptiste Daroussin h->h_last = nh->h_last; 752*d0ef721eSBaptiste Daroussin h->h_prev = nh->h_prev; 753*d0ef721eSBaptiste Daroussin h->h_curr = nh->h_curr; 754*d0ef721eSBaptiste Daroussin h->h_set = nh->h_set; 755*d0ef721eSBaptiste Daroussin h->h_clear = nh->h_clear; 756*d0ef721eSBaptiste Daroussin h->h_enter = nh->h_enter; 757*d0ef721eSBaptiste Daroussin h->h_add = nh->h_add; 758*d0ef721eSBaptiste Daroussin h->h_del = nh->h_del; 759*d0ef721eSBaptiste Daroussin 760*d0ef721eSBaptiste Daroussin return 0; 761*d0ef721eSBaptiste Daroussin } 762*d0ef721eSBaptiste Daroussin 763*d0ef721eSBaptiste Daroussin 764*d0ef721eSBaptiste Daroussin /* history_load(): 765*d0ef721eSBaptiste Daroussin * TYPE(History) load function 766*d0ef721eSBaptiste Daroussin */ 767*d0ef721eSBaptiste Daroussin static int 768*d0ef721eSBaptiste Daroussin history_load(TYPE(History) *h, const char *fname) 769*d0ef721eSBaptiste Daroussin { 770*d0ef721eSBaptiste Daroussin FILE *fp; 771*d0ef721eSBaptiste Daroussin char *line; 772*d0ef721eSBaptiste Daroussin size_t llen; 773*d0ef721eSBaptiste Daroussin ssize_t sz; 774*d0ef721eSBaptiste Daroussin size_t max_size; 775*d0ef721eSBaptiste Daroussin char *ptr; 776*d0ef721eSBaptiste Daroussin int i = -1; 777*d0ef721eSBaptiste Daroussin TYPE(HistEvent) ev; 778*d0ef721eSBaptiste Daroussin Char *decode_result; 779*d0ef721eSBaptiste Daroussin #ifndef NARROWCHAR 780*d0ef721eSBaptiste Daroussin static ct_buffer_t conv; 781*d0ef721eSBaptiste Daroussin #endif 782*d0ef721eSBaptiste Daroussin 783*d0ef721eSBaptiste Daroussin if ((fp = fopen(fname, "r")) == NULL) 784*d0ef721eSBaptiste Daroussin return i; 785*d0ef721eSBaptiste Daroussin 786*d0ef721eSBaptiste Daroussin line = NULL; 787*d0ef721eSBaptiste Daroussin llen = 0; 788*d0ef721eSBaptiste Daroussin if ((sz = getline(&line, &llen, fp)) == -1) 789*d0ef721eSBaptiste Daroussin goto done; 790*d0ef721eSBaptiste Daroussin 791*d0ef721eSBaptiste Daroussin if (strncmp(line, hist_cookie, (size_t)sz) != 0) 792*d0ef721eSBaptiste Daroussin goto done; 793*d0ef721eSBaptiste Daroussin 794*d0ef721eSBaptiste Daroussin ptr = h_malloc((max_size = 1024) * sizeof(*ptr)); 795*d0ef721eSBaptiste Daroussin if (ptr == NULL) 796*d0ef721eSBaptiste Daroussin goto done; 797*d0ef721eSBaptiste Daroussin for (i = 0; (sz = getline(&line, &llen, fp)) != -1; i++) { 798*d0ef721eSBaptiste Daroussin if (sz > 0 && line[sz - 1] == '\n') 799*d0ef721eSBaptiste Daroussin line[--sz] = '\0'; 800*d0ef721eSBaptiste Daroussin if (max_size < (size_t)sz) { 801*d0ef721eSBaptiste Daroussin char *nptr; 802*d0ef721eSBaptiste Daroussin max_size = ((size_t)sz + 1024) & (size_t)~1023; 803*d0ef721eSBaptiste Daroussin nptr = h_realloc(ptr, max_size * sizeof(*ptr)); 804*d0ef721eSBaptiste Daroussin if (nptr == NULL) { 805*d0ef721eSBaptiste Daroussin i = -1; 806*d0ef721eSBaptiste Daroussin goto oomem; 807*d0ef721eSBaptiste Daroussin } 808*d0ef721eSBaptiste Daroussin ptr = nptr; 809*d0ef721eSBaptiste Daroussin } 810*d0ef721eSBaptiste Daroussin (void) strunvis(ptr, line); 811*d0ef721eSBaptiste Daroussin decode_result = ct_decode_string(ptr, &conv); 812*d0ef721eSBaptiste Daroussin if (decode_result == NULL) 813*d0ef721eSBaptiste Daroussin continue; 814*d0ef721eSBaptiste Daroussin if (HENTER(h, &ev, decode_result) == -1) { 815*d0ef721eSBaptiste Daroussin i = -1; 816*d0ef721eSBaptiste Daroussin goto oomem; 817*d0ef721eSBaptiste Daroussin } 818*d0ef721eSBaptiste Daroussin } 819*d0ef721eSBaptiste Daroussin oomem: 820*d0ef721eSBaptiste Daroussin h_free(ptr); 821*d0ef721eSBaptiste Daroussin done: 822*d0ef721eSBaptiste Daroussin free(line); 823*d0ef721eSBaptiste Daroussin (void) fclose(fp); 824*d0ef721eSBaptiste Daroussin return i; 825*d0ef721eSBaptiste Daroussin } 826*d0ef721eSBaptiste Daroussin 827*d0ef721eSBaptiste Daroussin 828*d0ef721eSBaptiste Daroussin /* history_save_fp(): 829*d0ef721eSBaptiste Daroussin * TYPE(History) save function 830*d0ef721eSBaptiste Daroussin */ 831*d0ef721eSBaptiste Daroussin static int 832*d0ef721eSBaptiste Daroussin history_save_fp(TYPE(History) *h, size_t nelem, FILE *fp) 833*d0ef721eSBaptiste Daroussin { 834*d0ef721eSBaptiste Daroussin TYPE(HistEvent) ev; 835*d0ef721eSBaptiste Daroussin int i = -1, retval; 836*d0ef721eSBaptiste Daroussin size_t len, max_size; 837*d0ef721eSBaptiste Daroussin char *ptr; 838*d0ef721eSBaptiste Daroussin const char *str; 839*d0ef721eSBaptiste Daroussin #ifndef NARROWCHAR 840*d0ef721eSBaptiste Daroussin static ct_buffer_t conv; 841*d0ef721eSBaptiste Daroussin #endif 842*d0ef721eSBaptiste Daroussin 843*d0ef721eSBaptiste Daroussin if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1) 844*d0ef721eSBaptiste Daroussin goto done; 845*d0ef721eSBaptiste Daroussin if (ftell(fp) == 0 && fputs(hist_cookie, fp) == EOF) 846*d0ef721eSBaptiste Daroussin goto done; 847*d0ef721eSBaptiste Daroussin ptr = h_malloc((max_size = 1024) * sizeof(*ptr)); 848*d0ef721eSBaptiste Daroussin if (ptr == NULL) 849*d0ef721eSBaptiste Daroussin goto done; 850*d0ef721eSBaptiste Daroussin if (nelem != (size_t)-1) { 851*d0ef721eSBaptiste Daroussin for (retval = HFIRST(h, &ev); retval != -1 && nelem-- > 0; 852*d0ef721eSBaptiste Daroussin retval = HNEXT(h, &ev)) 853*d0ef721eSBaptiste Daroussin continue; 854*d0ef721eSBaptiste Daroussin } else 855*d0ef721eSBaptiste Daroussin retval = -1; 856*d0ef721eSBaptiste Daroussin 857*d0ef721eSBaptiste Daroussin if (retval == -1) 858*d0ef721eSBaptiste Daroussin retval = HLAST(h, &ev); 859*d0ef721eSBaptiste Daroussin 860*d0ef721eSBaptiste Daroussin for (i = 0; retval != -1; retval = HPREV(h, &ev), i++) { 861*d0ef721eSBaptiste Daroussin str = ct_encode_string(ev.str, &conv); 862*d0ef721eSBaptiste Daroussin len = strlen(str) * 4 + 1; 863*d0ef721eSBaptiste Daroussin if (len > max_size) { 864*d0ef721eSBaptiste Daroussin char *nptr; 865*d0ef721eSBaptiste Daroussin max_size = (len + 1024) & (size_t)~1023; 866*d0ef721eSBaptiste Daroussin nptr = h_realloc(ptr, max_size * sizeof(*ptr)); 867*d0ef721eSBaptiste Daroussin if (nptr == NULL) { 868*d0ef721eSBaptiste Daroussin i = -1; 869*d0ef721eSBaptiste Daroussin goto oomem; 870*d0ef721eSBaptiste Daroussin } 871*d0ef721eSBaptiste Daroussin ptr = nptr; 872*d0ef721eSBaptiste Daroussin } 873*d0ef721eSBaptiste Daroussin (void) strvis(ptr, str, VIS_WHITE); 874*d0ef721eSBaptiste Daroussin (void) fprintf(fp, "%s\n", ptr); 875*d0ef721eSBaptiste Daroussin } 876*d0ef721eSBaptiste Daroussin oomem: 877*d0ef721eSBaptiste Daroussin h_free(ptr); 878*d0ef721eSBaptiste Daroussin done: 879*d0ef721eSBaptiste Daroussin return i; 880*d0ef721eSBaptiste Daroussin } 881*d0ef721eSBaptiste Daroussin 882*d0ef721eSBaptiste Daroussin 883*d0ef721eSBaptiste Daroussin /* history_save(): 884*d0ef721eSBaptiste Daroussin * History save function 885*d0ef721eSBaptiste Daroussin */ 886*d0ef721eSBaptiste Daroussin static int 887*d0ef721eSBaptiste Daroussin history_save(TYPE(History) *h, const char *fname) 888*d0ef721eSBaptiste Daroussin { 889*d0ef721eSBaptiste Daroussin FILE *fp; 890*d0ef721eSBaptiste Daroussin int i; 891*d0ef721eSBaptiste Daroussin 892*d0ef721eSBaptiste Daroussin if ((fp = fopen(fname, "w")) == NULL) 893*d0ef721eSBaptiste Daroussin return -1; 894*d0ef721eSBaptiste Daroussin 895*d0ef721eSBaptiste Daroussin i = history_save_fp(h, (size_t)-1, fp); 896*d0ef721eSBaptiste Daroussin 897*d0ef721eSBaptiste Daroussin (void) fclose(fp); 898*d0ef721eSBaptiste Daroussin return i; 899*d0ef721eSBaptiste Daroussin } 900*d0ef721eSBaptiste Daroussin 901*d0ef721eSBaptiste Daroussin 902*d0ef721eSBaptiste Daroussin /* history_prev_event(): 903*d0ef721eSBaptiste Daroussin * Find the previous event, with number given 904*d0ef721eSBaptiste Daroussin */ 905*d0ef721eSBaptiste Daroussin static int 906*d0ef721eSBaptiste Daroussin history_prev_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num) 907*d0ef721eSBaptiste Daroussin { 908*d0ef721eSBaptiste Daroussin int retval; 909*d0ef721eSBaptiste Daroussin 910*d0ef721eSBaptiste Daroussin for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) 911*d0ef721eSBaptiste Daroussin if (ev->num == num) 912*d0ef721eSBaptiste Daroussin return 0; 913*d0ef721eSBaptiste Daroussin 914*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_NOT_FOUND); 915*d0ef721eSBaptiste Daroussin return -1; 916*d0ef721eSBaptiste Daroussin } 917*d0ef721eSBaptiste Daroussin 918*d0ef721eSBaptiste Daroussin 919*d0ef721eSBaptiste Daroussin static int 920*d0ef721eSBaptiste Daroussin history_next_evdata(TYPE(History) *h, TYPE(HistEvent) *ev, int num, void **d) 921*d0ef721eSBaptiste Daroussin { 922*d0ef721eSBaptiste Daroussin int retval; 923*d0ef721eSBaptiste Daroussin 924*d0ef721eSBaptiste Daroussin for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) 925*d0ef721eSBaptiste Daroussin if (ev->num == num) { 926*d0ef721eSBaptiste Daroussin if (d) 927*d0ef721eSBaptiste Daroussin *d = ((history_t *)h->h_ref)->cursor->data; 928*d0ef721eSBaptiste Daroussin return 0; 929*d0ef721eSBaptiste Daroussin } 930*d0ef721eSBaptiste Daroussin 931*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_NOT_FOUND); 932*d0ef721eSBaptiste Daroussin return -1; 933*d0ef721eSBaptiste Daroussin } 934*d0ef721eSBaptiste Daroussin 935*d0ef721eSBaptiste Daroussin 936*d0ef721eSBaptiste Daroussin /* history_next_event(): 937*d0ef721eSBaptiste Daroussin * Find the next event, with number given 938*d0ef721eSBaptiste Daroussin */ 939*d0ef721eSBaptiste Daroussin static int 940*d0ef721eSBaptiste Daroussin history_next_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num) 941*d0ef721eSBaptiste Daroussin { 942*d0ef721eSBaptiste Daroussin int retval; 943*d0ef721eSBaptiste Daroussin 944*d0ef721eSBaptiste Daroussin for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev)) 945*d0ef721eSBaptiste Daroussin if (ev->num == num) 946*d0ef721eSBaptiste Daroussin return 0; 947*d0ef721eSBaptiste Daroussin 948*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_NOT_FOUND); 949*d0ef721eSBaptiste Daroussin return -1; 950*d0ef721eSBaptiste Daroussin } 951*d0ef721eSBaptiste Daroussin 952*d0ef721eSBaptiste Daroussin 953*d0ef721eSBaptiste Daroussin /* history_prev_string(): 954*d0ef721eSBaptiste Daroussin * Find the previous event beginning with string 955*d0ef721eSBaptiste Daroussin */ 956*d0ef721eSBaptiste Daroussin static int 957*d0ef721eSBaptiste Daroussin history_prev_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str) 958*d0ef721eSBaptiste Daroussin { 959*d0ef721eSBaptiste Daroussin size_t len = Strlen(str); 960*d0ef721eSBaptiste Daroussin int retval; 961*d0ef721eSBaptiste Daroussin 962*d0ef721eSBaptiste Daroussin for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev)) 963*d0ef721eSBaptiste Daroussin if (Strncmp(str, ev->str, len) == 0) 964*d0ef721eSBaptiste Daroussin return 0; 965*d0ef721eSBaptiste Daroussin 966*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_NOT_FOUND); 967*d0ef721eSBaptiste Daroussin return -1; 968*d0ef721eSBaptiste Daroussin } 969*d0ef721eSBaptiste Daroussin 970*d0ef721eSBaptiste Daroussin 971*d0ef721eSBaptiste Daroussin /* history_next_string(): 972*d0ef721eSBaptiste Daroussin * Find the next event beginning with string 973*d0ef721eSBaptiste Daroussin */ 974*d0ef721eSBaptiste Daroussin static int 975*d0ef721eSBaptiste Daroussin history_next_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str) 976*d0ef721eSBaptiste Daroussin { 977*d0ef721eSBaptiste Daroussin size_t len = Strlen(str); 978*d0ef721eSBaptiste Daroussin int retval; 979*d0ef721eSBaptiste Daroussin 980*d0ef721eSBaptiste Daroussin for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) 981*d0ef721eSBaptiste Daroussin if (Strncmp(str, ev->str, len) == 0) 982*d0ef721eSBaptiste Daroussin return 0; 983*d0ef721eSBaptiste Daroussin 984*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_NOT_FOUND); 985*d0ef721eSBaptiste Daroussin return -1; 986*d0ef721eSBaptiste Daroussin } 987*d0ef721eSBaptiste Daroussin 988*d0ef721eSBaptiste Daroussin 989*d0ef721eSBaptiste Daroussin /* history(): 990*d0ef721eSBaptiste Daroussin * User interface to history functions. 991*d0ef721eSBaptiste Daroussin */ 992*d0ef721eSBaptiste Daroussin int 993*d0ef721eSBaptiste Daroussin FUNW(history)(TYPE(History) *h, TYPE(HistEvent) *ev, int fun, ...) 994*d0ef721eSBaptiste Daroussin { 995*d0ef721eSBaptiste Daroussin va_list va; 996*d0ef721eSBaptiste Daroussin const Char *str; 997*d0ef721eSBaptiste Daroussin int retval; 998*d0ef721eSBaptiste Daroussin 999*d0ef721eSBaptiste Daroussin va_start(va, fun); 1000*d0ef721eSBaptiste Daroussin 1001*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_OK); 1002*d0ef721eSBaptiste Daroussin 1003*d0ef721eSBaptiste Daroussin switch (fun) { 1004*d0ef721eSBaptiste Daroussin case H_GETSIZE: 1005*d0ef721eSBaptiste Daroussin retval = history_getsize(h, ev); 1006*d0ef721eSBaptiste Daroussin break; 1007*d0ef721eSBaptiste Daroussin 1008*d0ef721eSBaptiste Daroussin case H_SETSIZE: 1009*d0ef721eSBaptiste Daroussin retval = history_setsize(h, ev, va_arg(va, int)); 1010*d0ef721eSBaptiste Daroussin break; 1011*d0ef721eSBaptiste Daroussin 1012*d0ef721eSBaptiste Daroussin case H_GETUNIQUE: 1013*d0ef721eSBaptiste Daroussin retval = history_getunique(h, ev); 1014*d0ef721eSBaptiste Daroussin break; 1015*d0ef721eSBaptiste Daroussin 1016*d0ef721eSBaptiste Daroussin case H_SETUNIQUE: 1017*d0ef721eSBaptiste Daroussin retval = history_setunique(h, ev, va_arg(va, int)); 1018*d0ef721eSBaptiste Daroussin break; 1019*d0ef721eSBaptiste Daroussin 1020*d0ef721eSBaptiste Daroussin case H_ADD: 1021*d0ef721eSBaptiste Daroussin str = va_arg(va, const Char *); 1022*d0ef721eSBaptiste Daroussin retval = HADD(h, ev, str); 1023*d0ef721eSBaptiste Daroussin break; 1024*d0ef721eSBaptiste Daroussin 1025*d0ef721eSBaptiste Daroussin case H_DEL: 1026*d0ef721eSBaptiste Daroussin retval = HDEL(h, ev, va_arg(va, const int)); 1027*d0ef721eSBaptiste Daroussin break; 1028*d0ef721eSBaptiste Daroussin 1029*d0ef721eSBaptiste Daroussin case H_ENTER: 1030*d0ef721eSBaptiste Daroussin str = va_arg(va, const Char *); 1031*d0ef721eSBaptiste Daroussin if ((retval = HENTER(h, ev, str)) != -1) 1032*d0ef721eSBaptiste Daroussin h->h_ent = ev->num; 1033*d0ef721eSBaptiste Daroussin break; 1034*d0ef721eSBaptiste Daroussin 1035*d0ef721eSBaptiste Daroussin case H_APPEND: 1036*d0ef721eSBaptiste Daroussin str = va_arg(va, const Char *); 1037*d0ef721eSBaptiste Daroussin if ((retval = HSET(h, ev, h->h_ent)) != -1) 1038*d0ef721eSBaptiste Daroussin retval = HADD(h, ev, str); 1039*d0ef721eSBaptiste Daroussin break; 1040*d0ef721eSBaptiste Daroussin 1041*d0ef721eSBaptiste Daroussin case H_FIRST: 1042*d0ef721eSBaptiste Daroussin retval = HFIRST(h, ev); 1043*d0ef721eSBaptiste Daroussin break; 1044*d0ef721eSBaptiste Daroussin 1045*d0ef721eSBaptiste Daroussin case H_NEXT: 1046*d0ef721eSBaptiste Daroussin retval = HNEXT(h, ev); 1047*d0ef721eSBaptiste Daroussin break; 1048*d0ef721eSBaptiste Daroussin 1049*d0ef721eSBaptiste Daroussin case H_LAST: 1050*d0ef721eSBaptiste Daroussin retval = HLAST(h, ev); 1051*d0ef721eSBaptiste Daroussin break; 1052*d0ef721eSBaptiste Daroussin 1053*d0ef721eSBaptiste Daroussin case H_PREV: 1054*d0ef721eSBaptiste Daroussin retval = HPREV(h, ev); 1055*d0ef721eSBaptiste Daroussin break; 1056*d0ef721eSBaptiste Daroussin 1057*d0ef721eSBaptiste Daroussin case H_CURR: 1058*d0ef721eSBaptiste Daroussin retval = HCURR(h, ev); 1059*d0ef721eSBaptiste Daroussin break; 1060*d0ef721eSBaptiste Daroussin 1061*d0ef721eSBaptiste Daroussin case H_SET: 1062*d0ef721eSBaptiste Daroussin retval = HSET(h, ev, va_arg(va, const int)); 1063*d0ef721eSBaptiste Daroussin break; 1064*d0ef721eSBaptiste Daroussin 1065*d0ef721eSBaptiste Daroussin case H_CLEAR: 1066*d0ef721eSBaptiste Daroussin HCLEAR(h, ev); 1067*d0ef721eSBaptiste Daroussin retval = 0; 1068*d0ef721eSBaptiste Daroussin break; 1069*d0ef721eSBaptiste Daroussin 1070*d0ef721eSBaptiste Daroussin case H_LOAD: 1071*d0ef721eSBaptiste Daroussin retval = history_load(h, va_arg(va, const char *)); 1072*d0ef721eSBaptiste Daroussin if (retval == -1) 1073*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_HIST_READ); 1074*d0ef721eSBaptiste Daroussin break; 1075*d0ef721eSBaptiste Daroussin 1076*d0ef721eSBaptiste Daroussin case H_SAVE: 1077*d0ef721eSBaptiste Daroussin retval = history_save(h, va_arg(va, const char *)); 1078*d0ef721eSBaptiste Daroussin if (retval == -1) 1079*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_HIST_WRITE); 1080*d0ef721eSBaptiste Daroussin break; 1081*d0ef721eSBaptiste Daroussin 1082*d0ef721eSBaptiste Daroussin case H_SAVE_FP: 1083*d0ef721eSBaptiste Daroussin retval = history_save_fp(h, (size_t)-1, va_arg(va, FILE *)); 1084*d0ef721eSBaptiste Daroussin if (retval == -1) 1085*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_HIST_WRITE); 1086*d0ef721eSBaptiste Daroussin break; 1087*d0ef721eSBaptiste Daroussin 1088*d0ef721eSBaptiste Daroussin case H_NSAVE_FP: 1089*d0ef721eSBaptiste Daroussin { 1090*d0ef721eSBaptiste Daroussin size_t sz = va_arg(va, size_t); 1091*d0ef721eSBaptiste Daroussin retval = history_save_fp(h, sz, va_arg(va, FILE *)); 1092*d0ef721eSBaptiste Daroussin if (retval == -1) 1093*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_HIST_WRITE); 1094*d0ef721eSBaptiste Daroussin break; 1095*d0ef721eSBaptiste Daroussin } 1096*d0ef721eSBaptiste Daroussin 1097*d0ef721eSBaptiste Daroussin case H_PREV_EVENT: 1098*d0ef721eSBaptiste Daroussin retval = history_prev_event(h, ev, va_arg(va, int)); 1099*d0ef721eSBaptiste Daroussin break; 1100*d0ef721eSBaptiste Daroussin 1101*d0ef721eSBaptiste Daroussin case H_NEXT_EVENT: 1102*d0ef721eSBaptiste Daroussin retval = history_next_event(h, ev, va_arg(va, int)); 1103*d0ef721eSBaptiste Daroussin break; 1104*d0ef721eSBaptiste Daroussin 1105*d0ef721eSBaptiste Daroussin case H_PREV_STR: 1106*d0ef721eSBaptiste Daroussin retval = history_prev_string(h, ev, va_arg(va, const Char *)); 1107*d0ef721eSBaptiste Daroussin break; 1108*d0ef721eSBaptiste Daroussin 1109*d0ef721eSBaptiste Daroussin case H_NEXT_STR: 1110*d0ef721eSBaptiste Daroussin retval = history_next_string(h, ev, va_arg(va, const Char *)); 1111*d0ef721eSBaptiste Daroussin break; 1112*d0ef721eSBaptiste Daroussin 1113*d0ef721eSBaptiste Daroussin case H_FUNC: 1114*d0ef721eSBaptiste Daroussin { 1115*d0ef721eSBaptiste Daroussin TYPE(History) hf; 1116*d0ef721eSBaptiste Daroussin 1117*d0ef721eSBaptiste Daroussin hf.h_ref = va_arg(va, void *); 1118*d0ef721eSBaptiste Daroussin h->h_ent = -1; 1119*d0ef721eSBaptiste Daroussin hf.h_first = va_arg(va, history_gfun_t); 1120*d0ef721eSBaptiste Daroussin hf.h_next = va_arg(va, history_gfun_t); 1121*d0ef721eSBaptiste Daroussin hf.h_last = va_arg(va, history_gfun_t); 1122*d0ef721eSBaptiste Daroussin hf.h_prev = va_arg(va, history_gfun_t); 1123*d0ef721eSBaptiste Daroussin hf.h_curr = va_arg(va, history_gfun_t); 1124*d0ef721eSBaptiste Daroussin hf.h_set = va_arg(va, history_sfun_t); 1125*d0ef721eSBaptiste Daroussin hf.h_clear = va_arg(va, history_vfun_t); 1126*d0ef721eSBaptiste Daroussin hf.h_enter = va_arg(va, history_efun_t); 1127*d0ef721eSBaptiste Daroussin hf.h_add = va_arg(va, history_efun_t); 1128*d0ef721eSBaptiste Daroussin hf.h_del = va_arg(va, history_sfun_t); 1129*d0ef721eSBaptiste Daroussin 1130*d0ef721eSBaptiste Daroussin if ((retval = history_set_fun(h, &hf)) == -1) 1131*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_PARAM_MISSING); 1132*d0ef721eSBaptiste Daroussin break; 1133*d0ef721eSBaptiste Daroussin } 1134*d0ef721eSBaptiste Daroussin 1135*d0ef721eSBaptiste Daroussin case H_END: 1136*d0ef721eSBaptiste Daroussin FUN(history,end)(h); 1137*d0ef721eSBaptiste Daroussin retval = 0; 1138*d0ef721eSBaptiste Daroussin break; 1139*d0ef721eSBaptiste Daroussin 1140*d0ef721eSBaptiste Daroussin case H_NEXT_EVDATA: 1141*d0ef721eSBaptiste Daroussin { 1142*d0ef721eSBaptiste Daroussin int num = va_arg(va, int); 1143*d0ef721eSBaptiste Daroussin void **d = va_arg(va, void **); 1144*d0ef721eSBaptiste Daroussin retval = history_next_evdata(h, ev, num, d); 1145*d0ef721eSBaptiste Daroussin break; 1146*d0ef721eSBaptiste Daroussin } 1147*d0ef721eSBaptiste Daroussin 1148*d0ef721eSBaptiste Daroussin case H_DELDATA: 1149*d0ef721eSBaptiste Daroussin { 1150*d0ef721eSBaptiste Daroussin int num = va_arg(va, int); 1151*d0ef721eSBaptiste Daroussin void **d = va_arg(va, void **); 1152*d0ef721eSBaptiste Daroussin retval = history_deldata_nth((history_t *)h->h_ref, ev, num, d); 1153*d0ef721eSBaptiste Daroussin break; 1154*d0ef721eSBaptiste Daroussin } 1155*d0ef721eSBaptiste Daroussin 1156*d0ef721eSBaptiste Daroussin case H_REPLACE: /* only use after H_NEXT_EVDATA */ 1157*d0ef721eSBaptiste Daroussin { 1158*d0ef721eSBaptiste Daroussin const Char *line = va_arg(va, const Char *); 1159*d0ef721eSBaptiste Daroussin void *d = va_arg(va, void *); 1160*d0ef721eSBaptiste Daroussin const Char *s; 1161*d0ef721eSBaptiste Daroussin if(!line || !(s = Strdup(line))) { 1162*d0ef721eSBaptiste Daroussin retval = -1; 1163*d0ef721eSBaptiste Daroussin break; 1164*d0ef721eSBaptiste Daroussin } 1165*d0ef721eSBaptiste Daroussin ((history_t *)h->h_ref)->cursor->ev.str = s; 1166*d0ef721eSBaptiste Daroussin ((history_t *)h->h_ref)->cursor->data = d; 1167*d0ef721eSBaptiste Daroussin retval = 0; 1168*d0ef721eSBaptiste Daroussin break; 1169*d0ef721eSBaptiste Daroussin } 1170*d0ef721eSBaptiste Daroussin 1171*d0ef721eSBaptiste Daroussin default: 1172*d0ef721eSBaptiste Daroussin retval = -1; 1173*d0ef721eSBaptiste Daroussin he_seterrev(ev, _HE_UNKNOWN); 1174*d0ef721eSBaptiste Daroussin break; 1175*d0ef721eSBaptiste Daroussin } 1176*d0ef721eSBaptiste Daroussin va_end(va); 1177*d0ef721eSBaptiste Daroussin return retval; 1178*d0ef721eSBaptiste Daroussin } 1179