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