Annotation of src/lib/libedit/hist.c, Revision 1.28
1.28 ! christos 1: /* $NetBSD: hist.c,v 1.27 2016/04/11 00:22:48 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.28 ! christos 40: __RCSID("$NetBSD: hist.c,v 1.27 2016/04/11 00:22:48 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>
1.24 christos 48: #include <string.h>
49:
1.1 cgd 50: #include "el.h"
51:
52: /* hist_init():
53: * Initialization function.
54: */
55: protected int
1.6 lukem 56: hist_init(EditLine *el)
1.1 cgd 57: {
1.6 lukem 58:
59: el->el_history.fun = NULL;
60: el->el_history.ref = NULL;
1.16 christos 61: el->el_history.buf = el_malloc(EL_BUFSIZ * sizeof(*el->el_history.buf));
1.8 jdolecek 62: el->el_history.sz = EL_BUFSIZ;
1.7 christos 63: if (el->el_history.buf == NULL)
1.20 christos 64: return -1;
1.6 lukem 65: el->el_history.last = el->el_history.buf;
1.20 christos 66: return 0;
1.1 cgd 67: }
68:
69:
70: /* hist_end():
71: * clean up history;
72: */
73: protected void
1.6 lukem 74: hist_end(EditLine *el)
1.1 cgd 75: {
1.6 lukem 76:
1.19 christos 77: el_free(el->el_history.buf);
1.6 lukem 78: el->el_history.buf = NULL;
1.1 cgd 79: }
80:
81:
82: /* hist_set():
83: * Set new history interface
84: */
85: protected int
1.19 christos 86: hist_set(EditLine *el, hist_fun_t fun, void *ptr)
1.6 lukem 87: {
1.1 cgd 88:
1.6 lukem 89: el->el_history.ref = ptr;
90: el->el_history.fun = fun;
1.20 christos 91: return 0;
1.1 cgd 92: }
93:
94:
95: /* hist_get():
96: * Get a history line and update it in the buffer.
97: * eventno tells us the event to get.
98: */
99: protected el_action_t
1.6 lukem 100: hist_get(EditLine *el)
1.1 cgd 101: {
1.28 ! christos 102: const wchar_t *hp;
1.6 lukem 103: int h;
1.1 cgd 104:
1.6 lukem 105: if (el->el_history.eventno == 0) { /* if really the current line */
1.27 christos 106: (void) wcsncpy(el->el_line.buffer, el->el_history.buf,
1.8 jdolecek 107: el->el_history.sz);
1.6 lukem 108: el->el_line.lastchar = el->el_line.buffer +
109: (el->el_history.last - el->el_history.buf);
1.1 cgd 110:
111: #ifdef KSHVI
1.6 lukem 112: if (el->el_map.type == MAP_VI)
113: el->el_line.cursor = el->el_line.buffer;
114: else
1.1 cgd 115: #endif /* KSHVI */
1.6 lukem 116: el->el_line.cursor = el->el_line.lastchar;
1.1 cgd 117:
1.20 christos 118: return CC_REFRESH;
1.6 lukem 119: }
120: if (el->el_history.ref == NULL)
1.20 christos 121: return CC_ERROR;
1.1 cgd 122:
1.6 lukem 123: hp = HIST_FIRST(el);
1.1 cgd 124:
1.6 lukem 125: if (hp == NULL)
1.20 christos 126: return CC_ERROR;
1.1 cgd 127:
1.6 lukem 128: for (h = 1; h < el->el_history.eventno; h++)
129: if ((hp = HIST_NEXT(el)) == NULL) {
130: el->el_history.eventno = h;
1.20 christos 131: return CC_ERROR;
1.6 lukem 132: }
1.27 christos 133: (void) wcsncpy(el->el_line.buffer, hp,
1.9 christos 134: (size_t)(el->el_line.limit - el->el_line.buffer));
1.16 christos 135: el->el_line.buffer[el->el_line.limit - el->el_line.buffer - 1] = '\0';
1.27 christos 136: el->el_line.lastchar = el->el_line.buffer + wcslen(el->el_line.buffer);
1.6 lukem 137:
1.11 christos 138: if (el->el_line.lastchar > el->el_line.buffer
139: && el->el_line.lastchar[-1] == '\n')
140: el->el_line.lastchar--;
141: if (el->el_line.lastchar > el->el_line.buffer
142: && el->el_line.lastchar[-1] == ' ')
143: el->el_line.lastchar--;
1.1 cgd 144: #ifdef KSHVI
1.6 lukem 145: if (el->el_map.type == MAP_VI)
146: el->el_line.cursor = el->el_line.buffer;
147: else
1.1 cgd 148: #endif /* KSHVI */
1.6 lukem 149: el->el_line.cursor = el->el_line.lastchar;
1.1 cgd 150:
1.20 christos 151: return CC_REFRESH;
1.1 cgd 152: }
153:
1.6 lukem 154:
1.12 christos 155: /* hist_command()
156: * process a history command
1.1 cgd 157: */
158: protected int
1.28 ! christos 159: hist_command(EditLine *el, int argc, const wchar_t **argv)
1.1 cgd 160: {
1.28 ! christos 161: const wchar_t *str;
1.12 christos 162: int num;
1.27 christos 163: HistEventW ev;
1.1 cgd 164:
1.6 lukem 165: if (el->el_history.ref == NULL)
1.20 christos 166: return -1;
1.12 christos 167:
1.27 christos 168: if (argc == 1 || wcscmp(argv[1], L"list") == 0) {
1.12 christos 169: /* List history entries */
170:
171: for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
172: (void) fprintf(el->el_outfile, "%d %s",
1.16 christos 173: el->el_history.ev.num, ct_encode_string(str, &el->el_scratch));
1.20 christos 174: return 0;
1.12 christos 175: }
176:
1.15 christos 177: if (argc != 3)
1.20 christos 178: return -1;
1.12 christos 179:
1.26 christos 180: num = (int)wcstol(argv[2], NULL, 0);
1.12 christos 181:
1.27 christos 182: if (wcscmp(argv[1], L"size") == 0)
183: return history_w(el->el_history.ref, &ev, H_SETSIZE, num);
1.12 christos 184:
1.27 christos 185: if (wcscmp(argv[1], L"unique") == 0)
186: return history_w(el->el_history.ref, &ev, H_SETUNIQUE, num);
1.12 christos 187:
188: return -1;
1.8 jdolecek 189: }
190:
191: /* hist_enlargebuf()
192: * Enlarge history buffer to specified value. Called from el_enlargebufs().
193: * Return 0 for failure, 1 for success.
194: */
195: protected int
196: /*ARGSUSED*/
197: hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
198: {
1.28 ! christos 199: wchar_t *newbuf;
1.8 jdolecek 200:
1.16 christos 201: newbuf = el_realloc(el->el_history.buf, newsz * sizeof(*newbuf));
1.8 jdolecek 202: if (!newbuf)
203: return 0;
204:
1.16 christos 205: (void) memset(&newbuf[oldsz], '\0', (newsz - oldsz) * sizeof(*newbuf));
1.8 jdolecek 206:
207: el->el_history.last = newbuf +
208: (el->el_history.last - el->el_history.buf);
209: el->el_history.buf = newbuf;
210: el->el_history.sz = newsz;
211:
212: return 1;
1.1 cgd 213: }
1.17 christos 214:
215: protected wchar_t *
1.19 christos 216: hist_convert(EditLine *el, int fn, void *arg)
1.17 christos 217: {
218: HistEventW ev;
219: if ((*(el)->el_history.fun)((el)->el_history.ref, &ev, fn, arg) == -1)
220: return NULL;
221: return ct_decode_string((const char *)(const void *)ev.str,
222: &el->el_scratch);
223: }
CVSweb <webmaster@jp.NetBSD.org>