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