hist.c revision 302408
1219820Sjeff/* $NetBSD: hist.c,v 1.20 2011/07/29 15:16:33 christos Exp $ */ 2219820Sjeff 3219820Sjeff/*- 4219820Sjeff * Copyright (c) 1992, 1993 5219820Sjeff * The Regents of the University of California. All rights reserved. 6219820Sjeff * 7219820Sjeff * This code is derived from software contributed to Berkeley by 8219820Sjeff * Christos Zoulas of Cornell University. 9219820Sjeff * 10219820Sjeff * Redistribution and use in source and binary forms, with or without 11219820Sjeff * modification, are permitted provided that the following conditions 12219820Sjeff * are met: 13219820Sjeff * 1. Redistributions of source code must retain the above copyright 14219820Sjeff * notice, this list of conditions and the following disclaimer. 15219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright 16219820Sjeff * notice, this list of conditions and the following disclaimer in the 17219820Sjeff * documentation and/or other materials provided with the distribution. 18219820Sjeff * 3. Neither the name of the University nor the names of its contributors 19219820Sjeff * may be used to endorse or promote products derived from this software 20219820Sjeff * without specific prior written permission. 21219820Sjeff * 22219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23219820Sjeff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24219820Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25219820Sjeff * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26219820Sjeff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27219820Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28219820Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29219820Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30219820Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31219820Sjeff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32219820Sjeff * SUCH DAMAGE. 33219820Sjeff */ 34219820Sjeff 35219820Sjeff#include "config.h" 36219820Sjeff#if !defined(lint) && !defined(SCCSID) 37219820Sjeff#if 0 38219820Sjeffstatic char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93"; 39219820Sjeff#else 40219820Sjeff__RCSID("$NetBSD: hist.c,v 1.20 2011/07/29 15:16:33 christos Exp $"); 41219820Sjeff#endif 42219820Sjeff#endif /* not lint && not SCCSID */ 43219820Sjeff#include <sys/cdefs.h> 44219820Sjeff__FBSDID("$FreeBSD: stable/11/lib/libedit/hist.c 296435 2016-03-06 21:32:54Z pfg $"); 45219820Sjeff 46219820Sjeff/* 47219820Sjeff * hist.c: History access functions 48219820Sjeff */ 49219820Sjeff#include <stdlib.h> 50219820Sjeff#include "el.h" 51219820Sjeff 52219820Sjeff/* hist_init(): 53219820Sjeff * Initialization function. 54219820Sjeff */ 55219820Sjeffprotected int 56219820Sjeffhist_init(EditLine *el) 57219820Sjeff{ 58219820Sjeff 59219820Sjeff el->el_history.fun = NULL; 60219820Sjeff el->el_history.ref = NULL; 61219820Sjeff el->el_history.buf = el_malloc(EL_BUFSIZ * sizeof(*el->el_history.buf)); 62219820Sjeff el->el_history.sz = EL_BUFSIZ; 63219820Sjeff if (el->el_history.buf == NULL) 64219820Sjeff return -1; 65219820Sjeff el->el_history.last = el->el_history.buf; 66219820Sjeff return 0; 67219820Sjeff} 68219820Sjeff 69219820Sjeff 70219820Sjeff/* hist_end(): 71219820Sjeff * clean up history; 72219820Sjeff */ 73219820Sjeffprotected void 74219820Sjeffhist_end(EditLine *el) 75219820Sjeff{ 76219820Sjeff 77219820Sjeff el_free(el->el_history.buf); 78219820Sjeff el->el_history.buf = NULL; 79219820Sjeff} 80219820Sjeff 81219820Sjeff 82219820Sjeff/* hist_set(): 83219820Sjeff * Set new history interface 84219820Sjeff */ 85219820Sjeffprotected int 86219820Sjeffhist_set(EditLine *el, hist_fun_t fun, void *ptr) 87219820Sjeff{ 88219820Sjeff 89219820Sjeff el->el_history.ref = ptr; 90219820Sjeff el->el_history.fun = fun; 91219820Sjeff return 0; 92219820Sjeff} 93219820Sjeff 94219820Sjeff 95219820Sjeff/* hist_get(): 96219820Sjeff * Get a history line and update it in the buffer. 97219820Sjeff * eventno tells us the event to get. 98219820Sjeff */ 99219820Sjeffprotected el_action_t 100219820Sjeffhist_get(EditLine *el) 101219820Sjeff{ 102219820Sjeff const Char *hp; 103219820Sjeff int h; 104219820Sjeff 105219820Sjeff if (el->el_history.eventno == 0) { /* if really the current line */ 106219820Sjeff (void) Strncpy(el->el_line.buffer, el->el_history.buf, 107219820Sjeff el->el_history.sz); 108219820Sjeff el->el_line.lastchar = el->el_line.buffer + 109219820Sjeff (el->el_history.last - el->el_history.buf); 110219820Sjeff 111219820Sjeff#ifdef KSHVI 112219820Sjeff if (el->el_map.type == MAP_VI) 113219820Sjeff el->el_line.cursor = el->el_line.buffer; 114219820Sjeff else 115219820Sjeff#endif /* KSHVI */ 116219820Sjeff el->el_line.cursor = el->el_line.lastchar; 117219820Sjeff 118219820Sjeff return CC_REFRESH; 119219820Sjeff } 120219820Sjeff if (el->el_history.ref == NULL) 121219820Sjeff return CC_ERROR; 122219820Sjeff 123219820Sjeff hp = HIST_FIRST(el); 124219820Sjeff 125219820Sjeff if (hp == NULL) 126219820Sjeff return CC_ERROR; 127219820Sjeff 128219820Sjeff for (h = 1; h < el->el_history.eventno; h++) 129219820Sjeff if ((hp = HIST_NEXT(el)) == NULL) { 130219820Sjeff el->el_history.eventno = h; 131219820Sjeff return CC_ERROR; 132219820Sjeff } 133219820Sjeff (void) Strncpy(el->el_line.buffer, hp, 134219820Sjeff (size_t)(el->el_line.limit - el->el_line.buffer)); 135219820Sjeff el->el_line.buffer[el->el_line.limit - el->el_line.buffer - 1] = '\0'; 136219820Sjeff el->el_line.lastchar = el->el_line.buffer + Strlen(el->el_line.buffer); 137219820Sjeff 138219820Sjeff if (el->el_line.lastchar > el->el_line.buffer 139219820Sjeff && el->el_line.lastchar[-1] == '\n') 140219820Sjeff el->el_line.lastchar--; 141219820Sjeff if (el->el_line.lastchar > el->el_line.buffer 142219820Sjeff && el->el_line.lastchar[-1] == ' ') 143219820Sjeff el->el_line.lastchar--; 144219820Sjeff#ifdef KSHVI 145219820Sjeff if (el->el_map.type == MAP_VI) 146219820Sjeff el->el_line.cursor = el->el_line.buffer; 147219820Sjeff else 148219820Sjeff#endif /* KSHVI */ 149219820Sjeff el->el_line.cursor = el->el_line.lastchar; 150219820Sjeff 151219820Sjeff return CC_REFRESH; 152219820Sjeff} 153219820Sjeff 154219820Sjeff 155219820Sjeff/* hist_command() 156219820Sjeff * process a history command 157219820Sjeff */ 158219820Sjeffprotected int 159219820Sjeffhist_command(EditLine *el, int argc, const Char **argv) 160219820Sjeff{ 161219820Sjeff const Char *str; 162219820Sjeff int num; 163219820Sjeff TYPE(HistEvent) ev; 164219820Sjeff 165219820Sjeff if (el->el_history.ref == NULL) 166219820Sjeff return -1; 167219820Sjeff 168219820Sjeff if (argc == 1 || Strcmp(argv[1], STR("list")) == 0) { 169219820Sjeff /* List history entries */ 170219820Sjeff 171219820Sjeff for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el)) 172219820Sjeff (void) fprintf(el->el_outfile, "%d %s", 173219820Sjeff el->el_history.ev.num, ct_encode_string(str, &el->el_scratch)); 174219820Sjeff return 0; 175219820Sjeff } 176219820Sjeff 177219820Sjeff if (argc != 3) 178219820Sjeff return -1; 179219820Sjeff 180219820Sjeff num = (int)Strtol(argv[2], NULL, 0); 181219820Sjeff 182219820Sjeff if (Strcmp(argv[1], STR("size")) == 0) 183219820Sjeff return FUNW(history)(el->el_history.ref, &ev, H_SETSIZE, num); 184219820Sjeff 185219820Sjeff if (Strcmp(argv[1], STR("unique")) == 0) 186219820Sjeff return FUNW(history)(el->el_history.ref, &ev, H_SETUNIQUE, num); 187219820Sjeff 188219820Sjeff return -1; 189219820Sjeff} 190219820Sjeff 191219820Sjeff/* hist_enlargebuf() 192219820Sjeff * Enlarge history buffer to specified value. Called from el_enlargebufs(). 193219820Sjeff * Return 0 for failure, 1 for success. 194219820Sjeff */ 195219820Sjeffprotected int 196219820Sjeff/*ARGSUSED*/ 197219820Sjeffhist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz) 198219820Sjeff{ 199219820Sjeff Char *newbuf; 200219820Sjeff 201219820Sjeff newbuf = el_realloc(el->el_history.buf, newsz * sizeof(*newbuf)); 202219820Sjeff if (!newbuf) 203219820Sjeff return 0; 204219820Sjeff 205219820Sjeff (void) memset(&newbuf[oldsz], '\0', (newsz - oldsz) * sizeof(*newbuf)); 206219820Sjeff 207219820Sjeff el->el_history.last = newbuf + 208219820Sjeff (el->el_history.last - el->el_history.buf); 209219820Sjeff el->el_history.buf = newbuf; 210219820Sjeff el->el_history.sz = newsz; 211219820Sjeff 212219820Sjeff return 1; 213219820Sjeff} 214219820Sjeff 215219820Sjeff#ifdef WIDECHAR 216219820Sjeffprotected wchar_t * 217219820Sjeffhist_convert(EditLine *el, int fn, void *arg) 218219820Sjeff{ 219219820Sjeff HistEventW ev; 220219820Sjeff if ((*(el)->el_history.fun)((el)->el_history.ref, &ev, fn, arg) == -1) 221219820Sjeff return NULL; 222219820Sjeff return ct_decode_string((const char *)(const void *)ev.str, 223219820Sjeff &el->el_scratch); 224219820Sjeff} 225219820Sjeff#endif 226219820Sjeff