Annotation of src/lib/libedit/hist.c, Revision 1.20
1.20 ! christos 1: /* $NetBSD: hist.c,v 1.19 2011/07/28 20:50:55 christos Exp $ */
1.2 lukem 2:
1.1 cgd 3: /*-
4: * Copyright (c) 1992, 1993
5: * The Regents of the University of California. All rights reserved.
6: *
7: * This code is derived from software contributed to Berkeley by
8: * Christos Zoulas of Cornell University.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
1.14 agc 18: * 3. Neither the name of the University nor the names of its contributors
1.1 cgd 19: * may be used to endorse or promote products derived from this software
20: * without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32: * SUCH DAMAGE.
33: */
34:
1.10 christos 35: #include "config.h"
1.1 cgd 36: #if !defined(lint) && !defined(SCCSID)
1.2 lukem 37: #if 0
1.1 cgd 38: static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
1.2 lukem 39: #else
1.20 ! christos 40: __RCSID("$NetBSD: hist.c,v 1.19 2011/07/28 20:50:55 christos Exp $");
1.2 lukem 41: #endif
1.1 cgd 42: #endif /* not lint && not SCCSID */
43:
44: /*
45: * hist.c: History access functions
46: */
47: #include <stdlib.h>
48: #include "el.h"
49:
50: /* hist_init():
51: * Initialization function.
52: */
53: protected int
1.6 lukem 54: hist_init(EditLine *el)
1.1 cgd 55: {
1.6 lukem 56:
57: el->el_history.fun = NULL;
58: el->el_history.ref = NULL;
1.16 christos 59: el->el_history.buf = el_malloc(EL_BUFSIZ * sizeof(*el->el_history.buf));
1.8 jdolecek 60: el->el_history.sz = EL_BUFSIZ;
1.7 christos 61: if (el->el_history.buf == NULL)
1.20 ! christos 62: return -1;
1.6 lukem 63: el->el_history.last = el->el_history.buf;
1.20 ! christos 64: return 0;
1.1 cgd 65: }
66:
67:
68: /* hist_end():
69: * clean up history;
70: */
71: protected void
1.6 lukem 72: hist_end(EditLine *el)
1.1 cgd 73: {
1.6 lukem 74:
1.19 christos 75: el_free(el->el_history.buf);
1.6 lukem 76: el->el_history.buf = NULL;
1.1 cgd 77: }
78:
79:
80: /* hist_set():
81: * Set new history interface
82: */
83: protected int
1.19 christos 84: hist_set(EditLine *el, hist_fun_t fun, void *ptr)
1.6 lukem 85: {
1.1 cgd 86:
1.6 lukem 87: el->el_history.ref = ptr;
88: el->el_history.fun = fun;
1.20 ! christos 89: return 0;
1.1 cgd 90: }
91:
92:
93: /* hist_get():
94: * Get a history line and update it in the buffer.
95: * eventno tells us the event to get.
96: */
97: protected el_action_t
1.6 lukem 98: hist_get(EditLine *el)
1.1 cgd 99: {
1.16 christos 100: const Char *hp;
1.6 lukem 101: int h;
1.1 cgd 102:
1.6 lukem 103: if (el->el_history.eventno == 0) { /* if really the current line */
1.16 christos 104: (void) Strncpy(el->el_line.buffer, el->el_history.buf,
1.8 jdolecek 105: el->el_history.sz);
1.6 lukem 106: el->el_line.lastchar = el->el_line.buffer +
107: (el->el_history.last - el->el_history.buf);
1.1 cgd 108:
109: #ifdef KSHVI
1.6 lukem 110: if (el->el_map.type == MAP_VI)
111: el->el_line.cursor = el->el_line.buffer;
112: else
1.1 cgd 113: #endif /* KSHVI */
1.6 lukem 114: el->el_line.cursor = el->el_line.lastchar;
1.1 cgd 115:
1.20 ! christos 116: return CC_REFRESH;
1.6 lukem 117: }
118: if (el->el_history.ref == NULL)
1.20 ! christos 119: return CC_ERROR;
1.1 cgd 120:
1.6 lukem 121: hp = HIST_FIRST(el);
1.1 cgd 122:
1.6 lukem 123: if (hp == NULL)
1.20 ! christos 124: return CC_ERROR;
1.1 cgd 125:
1.6 lukem 126: for (h = 1; h < el->el_history.eventno; h++)
127: if ((hp = HIST_NEXT(el)) == NULL) {
128: el->el_history.eventno = h;
1.20 ! christos 129: return CC_ERROR;
1.6 lukem 130: }
1.16 christos 131: (void) Strncpy(el->el_line.buffer, hp,
1.9 christos 132: (size_t)(el->el_line.limit - el->el_line.buffer));
1.16 christos 133: el->el_line.buffer[el->el_line.limit - el->el_line.buffer - 1] = '\0';
134: el->el_line.lastchar = el->el_line.buffer + Strlen(el->el_line.buffer);
1.6 lukem 135:
1.11 christos 136: if (el->el_line.lastchar > el->el_line.buffer
137: && el->el_line.lastchar[-1] == '\n')
138: el->el_line.lastchar--;
139: if (el->el_line.lastchar > el->el_line.buffer
140: && el->el_line.lastchar[-1] == ' ')
141: el->el_line.lastchar--;
1.1 cgd 142: #ifdef KSHVI
1.6 lukem 143: if (el->el_map.type == MAP_VI)
144: el->el_line.cursor = el->el_line.buffer;
145: else
1.1 cgd 146: #endif /* KSHVI */
1.6 lukem 147: el->el_line.cursor = el->el_line.lastchar;
1.1 cgd 148:
1.20 ! christos 149: return CC_REFRESH;
1.1 cgd 150: }
151:
1.6 lukem 152:
1.12 christos 153: /* hist_command()
154: * process a history command
1.1 cgd 155: */
156: protected int
1.16 christos 157: hist_command(EditLine *el, int argc, const Char **argv)
1.1 cgd 158: {
1.16 christos 159: const Char *str;
1.12 christos 160: int num;
1.18 christos 161: TYPE(HistEvent) ev;
1.1 cgd 162:
1.6 lukem 163: if (el->el_history.ref == NULL)
1.20 ! christos 164: return -1;
1.12 christos 165:
1.16 christos 166: if (argc == 1 || Strcmp(argv[1], STR("list")) == 0) {
1.12 christos 167: /* List history entries */
168:
169: for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
170: (void) fprintf(el->el_outfile, "%d %s",
1.16 christos 171: el->el_history.ev.num, ct_encode_string(str, &el->el_scratch));
1.20 ! christos 172: return 0;
1.12 christos 173: }
174:
1.15 christos 175: if (argc != 3)
1.20 ! christos 176: return -1;
1.12 christos 177:
1.16 christos 178: num = (int)Strtol(argv[2], NULL, 0);
1.12 christos 179:
1.16 christos 180: if (Strcmp(argv[1], STR("size")) == 0)
1.18 christos 181: return FUNW(history)(el->el_history.ref, &ev, H_SETSIZE, num);
1.12 christos 182:
1.16 christos 183: if (Strcmp(argv[1], STR("unique")) == 0)
1.18 christos 184: return FUNW(history)(el->el_history.ref, &ev, H_SETUNIQUE, num);
1.12 christos 185:
186: return -1;
1.8 jdolecek 187: }
188:
189: /* hist_enlargebuf()
190: * Enlarge history buffer to specified value. Called from el_enlargebufs().
191: * Return 0 for failure, 1 for success.
192: */
193: protected int
194: /*ARGSUSED*/
195: hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
196: {
1.16 christos 197: Char *newbuf;
1.8 jdolecek 198:
1.16 christos 199: newbuf = el_realloc(el->el_history.buf, newsz * sizeof(*newbuf));
1.8 jdolecek 200: if (!newbuf)
201: return 0;
202:
1.16 christos 203: (void) memset(&newbuf[oldsz], '\0', (newsz - oldsz) * sizeof(*newbuf));
1.8 jdolecek 204:
205: el->el_history.last = newbuf +
206: (el->el_history.last - el->el_history.buf);
207: el->el_history.buf = newbuf;
208: el->el_history.sz = newsz;
209:
210: return 1;
1.1 cgd 211: }
1.17 christos 212:
213: #ifdef WIDECHAR
214: protected wchar_t *
1.19 christos 215: hist_convert(EditLine *el, int fn, void *arg)
1.17 christos 216: {
217: HistEventW ev;
218: if ((*(el)->el_history.fun)((el)->el_history.ref, &ev, fn, arg) == -1)
219: return NULL;
220: return ct_decode_string((const char *)(const void *)ev.str,
221: &el->el_scratch);
222: }
223: #endif
CVSweb <webmaster@jp.NetBSD.org>