1 /* $NetBSD: hist.c,v 1.20 2013/07/16 17:47:43 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1980, 1991, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 #ifndef lint 34 #if 0 35 static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 5/31/93"; 36 #else 37 __RCSID("$NetBSD: hist.c,v 1.20 2013/07/16 17:47:43 christos Exp $"); 38 #endif 39 #endif /* not lint */ 40 41 #include <sys/types.h> 42 43 #include <stdarg.h> 44 #include <stdlib.h> 45 46 #include "csh.h" 47 #include "extern.h" 48 49 static void hfree(struct Hist *); 50 static void dohist1(struct Hist *, int *, int, int); 51 static void phist(struct Hist *, int); 52 53 void 54 savehist(struct wordent *sp) 55 { 56 struct Hist *hp, *np; 57 Char *cp; 58 int histlen; 59 60 histlen = 0; 61 62 /* throw away null lines */ 63 if (sp->next->word[0] == '\n') 64 return; 65 cp = value(STRhistory); 66 if (*cp) { 67 Char *p = cp; 68 69 while (*p) { 70 if (!Isdigit(*p)) { 71 histlen = 0; 72 break; 73 } 74 histlen = histlen * 10 + *p++ - '0'; 75 } 76 } 77 for (hp = &Histlist; (np = hp->Hnext) != NULL;) 78 if (eventno - np->Href >= histlen || histlen == 0) 79 hp->Hnext = np->Hnext, hfree(np); 80 else 81 hp = np; 82 (void) enthist(++eventno, sp, 1); 83 } 84 85 #ifdef EDIT 86 void 87 loadhist(struct Hist *hp) { 88 char *h = NULL; 89 90 if (hi == NULL || hp == NULL) 91 return; 92 loadhist(hp->Hnext); 93 if (sprlex(&h, &hp->Hlex) != -1) { 94 HistEvent ev; 95 history(hi, &ev, H_ENTER, h); 96 } 97 } 98 #endif 99 100 struct Hist * 101 enthist(int event, struct wordent *lp, int docopy) 102 { 103 struct Hist *np; 104 105 #ifdef EDIT 106 if (hi) { 107 char *h = NULL; 108 if (sprlex(&h, lp) != -1) { 109 HistEvent ev; 110 history(hi, &ev, H_ENTER, h); 111 } 112 } 113 #endif 114 np = xmalloc(sizeof(*np)); 115 np->Hnum = np->Href = event; 116 if (docopy) { 117 copylex(&np->Hlex, lp); 118 } 119 else { 120 np->Hlex.next = lp->next; 121 lp->next->prev = &np->Hlex; 122 np->Hlex.prev = lp->prev; 123 lp->prev->next = &np->Hlex; 124 } 125 np->Hnext = Histlist.Hnext; 126 Histlist.Hnext = np; 127 return (np); 128 } 129 130 static void 131 hfree(struct Hist *hp) 132 { 133 freelex(&hp->Hlex); 134 xfree((ptr_t) hp); 135 } 136 137 void 138 /*ARGSUSED*/ 139 dohist(Char **v, struct command *t) 140 { 141 sigset_t nsigset; 142 int hflg, n, rflg; 143 144 hflg = 0; 145 rflg = 0; 146 147 if (getn(value(STRhistory)) == 0) 148 return; 149 if (setintr) { 150 sigemptyset(&nsigset); 151 (void)sigaddset(&nsigset, SIGINT); 152 (void)sigprocmask(SIG_UNBLOCK, &nsigset, NULL); 153 } 154 while (*++v && **v == '-') { 155 Char *vp = *v; 156 157 while (*++vp) 158 switch (*vp) { 159 case 'h': 160 hflg++; 161 break; 162 case 'r': 163 rflg++; 164 break; 165 case '-': /* ignore multiple '-'s */ 166 break; 167 default: 168 stderror(ERR_HISTUS); 169 /* NOTREACHED */ 170 } 171 } 172 if (*v) 173 n = getn(*v); 174 else { 175 n = getn(value(STRhistory)); 176 } 177 dohist1(Histlist.Hnext, &n, rflg, hflg); 178 } 179 180 static void 181 dohist1(struct Hist *hp, int *np, int rflg, int hflg) 182 { 183 int print; 184 185 print = (*np) > 0; 186 187 for (; hp != 0; hp = hp->Hnext) { 188 (*np)--; 189 hp->Href++; 190 if (rflg == 0) { 191 dohist1(hp->Hnext, np, rflg, hflg); 192 if (print) 193 phist(hp, hflg); 194 return; 195 } 196 if (*np >= 0) 197 phist(hp, hflg); 198 } 199 } 200 201 static void 202 phist(struct Hist *hp, int hflg) 203 { 204 if (hflg == 0) 205 (void)fprintf(cshout, "%6d\t", hp->Hnum); 206 prlex(cshout, &hp->Hlex); 207 } 208