The world's most popular open source database
00001 /* $NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $ */ 00002 00003 /*- 00004 * Copyright (c) 1992, 1993 00005 * The Regents of the University of California. All rights reserved. 00006 * 00007 * This code is derived from software contributed to Berkeley by 00008 * Christos Zoulas of Cornell University. 00009 * 00010 * Redistribution and use in source and binary forms, with or without 00011 * modification, are permitted provided that the following conditions 00012 * are met: 00013 * 1. Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * 2. Redistributions in binary form must reproduce the above copyright 00016 * notice, this list of conditions and the following disclaimer in the 00017 * documentation and/or other materials provided with the distribution. 00018 * 3. Neither the name of the University nor the names of its contributors 00019 * may be used to endorse or promote products derived from this software 00020 * without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 00023 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00025 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 00026 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00027 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00028 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00029 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00031 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00032 * SUCH DAMAGE. 00033 */ 00034 00035 #include <config.h> 00036 00037 /* 00038 * hist.c: History access functions 00039 */ 00040 #include <stdlib.h> 00041 #include "el.h" 00042 00043 /* hist_init(): 00044 * Initialization function. 00045 */ 00046 protected int 00047 hist_init(EditLine *el) 00048 { 00049 00050 el->el_history.fun = NULL; 00051 el->el_history.ref = NULL; 00052 el->el_history.buf = (char *) el_malloc(EL_BUFSIZ); 00053 el->el_history.sz = EL_BUFSIZ; 00054 if (el->el_history.buf == NULL) 00055 return (-1); 00056 el->el_history.last = el->el_history.buf; 00057 return (0); 00058 } 00059 00060 00061 /* hist_end(): 00062 * clean up history; 00063 */ 00064 protected void 00065 hist_end(EditLine *el) 00066 { 00067 00068 el_free((ptr_t) el->el_history.buf); 00069 el->el_history.buf = NULL; 00070 } 00071 00072 00073 /* hist_set(): 00074 * Set new history interface 00075 */ 00076 protected int 00077 hist_set(EditLine *el, hist_fun_t fun, ptr_t ptr) 00078 { 00079 00080 el->el_history.ref = ptr; 00081 el->el_history.fun = fun; 00082 return (0); 00083 } 00084 00085 00086 /* hist_get(): 00087 * Get a history line and update it in the buffer. 00088 * eventno tells us the event to get. 00089 */ 00090 protected el_action_t 00091 hist_get(EditLine *el) 00092 { 00093 const char *hp; 00094 int h; 00095 00096 if (el->el_history.eventno == 0) { /* if really the current line */ 00097 (void) strncpy(el->el_line.buffer, el->el_history.buf, 00098 el->el_history.sz); 00099 el->el_line.lastchar = el->el_line.buffer + 00100 (el->el_history.last - el->el_history.buf); 00101 00102 #ifdef KSHVI 00103 if (el->el_map.type == MAP_VI) 00104 el->el_line.cursor = el->el_line.buffer; 00105 else 00106 #endif /* KSHVI */ 00107 el->el_line.cursor = el->el_line.lastchar; 00108 00109 return (CC_REFRESH); 00110 } 00111 if (el->el_history.ref == NULL) 00112 return (CC_ERROR); 00113 00114 hp = HIST_FIRST(el); 00115 00116 if (hp == NULL) 00117 return (CC_ERROR); 00118 00119 for (h = 1; h < el->el_history.eventno; h++) 00120 if ((hp = HIST_NEXT(el)) == NULL) { 00121 el->el_history.eventno = h; 00122 return (CC_ERROR); 00123 } 00124 (void) strlcpy(el->el_line.buffer, hp, 00125 (size_t)(el->el_line.limit - el->el_line.buffer)); 00126 el->el_line.lastchar = el->el_line.buffer + strlen(el->el_line.buffer); 00127 00128 if (el->el_line.lastchar > el->el_line.buffer 00129 && el->el_line.lastchar[-1] == '\n') 00130 el->el_line.lastchar--; 00131 if (el->el_line.lastchar > el->el_line.buffer 00132 && el->el_line.lastchar[-1] == ' ') 00133 el->el_line.lastchar--; 00134 #ifdef KSHVI 00135 if (el->el_map.type == MAP_VI) 00136 el->el_line.cursor = el->el_line.buffer; 00137 else 00138 #endif /* KSHVI */ 00139 el->el_line.cursor = el->el_line.lastchar; 00140 00141 return (CC_REFRESH); 00142 } 00143 00144 00145 /* hist_command() 00146 * process a history command 00147 */ 00148 protected int 00149 hist_command(EditLine *el, int argc, const char **argv) 00150 { 00151 const char *str; 00152 int num; 00153 HistEvent ev; 00154 00155 if (el->el_history.ref == NULL) 00156 return (-1); 00157 00158 if (argc == 1 || strcmp(argv[1], "list") == 0) { 00159 /* List history entries */ 00160 00161 for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el)) 00162 (void) fprintf(el->el_outfile, "%d %s", 00163 el->el_history.ev.num, str); 00164 return (0); 00165 } 00166 00167 if (argc != 3) 00168 return (-1); 00169 00170 num = (int)strtol(argv[2], NULL, 0); 00171 00172 if (strcmp(argv[1], "size") == 0) 00173 return history(el->el_history.ref, &ev, H_SETSIZE, num); 00174 00175 if (strcmp(argv[1], "unique") == 0) 00176 return history(el->el_history.ref, &ev, H_SETUNIQUE, num); 00177 00178 return -1; 00179 } 00180 00181 /* hist_enlargebuf() 00182 * Enlarge history buffer to specified value. Called from el_enlargebufs(). 00183 * Return 0 for failure, 1 for success. 00184 */ 00185 protected int 00186 /*ARGSUSED*/ 00187 hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz) 00188 { 00189 char *newbuf; 00190 00191 newbuf = realloc(el->el_history.buf, newsz); 00192 if (!newbuf) 00193 return 0; 00194 00195 (void) memset(&newbuf[oldsz], '\0', newsz - oldsz); 00196 00197 el->el_history.last = newbuf + 00198 (el->el_history.last - el->el_history.buf); 00199 el->el_history.buf = newbuf; 00200 el->el_history.sz = newsz; 00201 00202 return 1; 00203 }
1.4.7

