1 /* $NetBSD: hist.c,v 1.18 2007/07/16 18:26:10 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.18 2007/07/16 18:26:10 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 struct Hist * 86 enthist(int event, struct wordent *lp, int docopy) 87 { 88 struct Hist *np; 89 90 np = (struct Hist *)xmalloc((size_t)sizeof(*np)); 91 np->Hnum = np->Href = event; 92 if (docopy) { 93 copylex(&np->Hlex, lp); 94 } 95 else { 96 np->Hlex.next = lp->next; 97 lp->next->prev = &np->Hlex; 98 np->Hlex.prev = lp->prev; 99 lp->prev->next = &np->Hlex; 100 } 101 np->Hnext = Histlist.Hnext; 102 Histlist.Hnext = np; 103 return (np); 104 } 105 106 static void 107 hfree(struct Hist *hp) 108 { 109 freelex(&hp->Hlex); 110 xfree((ptr_t) hp); 111 } 112 113 void 114 /*ARGSUSED*/ 115 dohist(Char **v, struct command *t) 116 { 117 sigset_t nsigset; 118 int hflg, n, rflg; 119 120 hflg = 0; 121 rflg = 0; 122 123 if (getn(value(STRhistory)) == 0) 124 return; 125 if (setintr) { 126 sigemptyset(&nsigset); 127 (void)sigaddset(&nsigset, SIGINT); 128 (void)sigprocmask(SIG_UNBLOCK, &nsigset, NULL); 129 } 130 while (*++v && **v == '-') { 131 Char *vp = *v; 132 133 while (*++vp) 134 switch (*vp) { 135 case 'h': 136 hflg++; 137 break; 138 case 'r': 139 rflg++; 140 break; 141 case '-': /* ignore multiple '-'s */ 142 break; 143 default: 144 stderror(ERR_HISTUS); 145 /* NOTREACHED */ 146 } 147 } 148 if (*v) 149 n = getn(*v); 150 else { 151 n = getn(value(STRhistory)); 152 } 153 dohist1(Histlist.Hnext, &n, rflg, hflg); 154 } 155 156 static void 157 dohist1(struct Hist *hp, int *np, int rflg, int hflg) 158 { 159 int print; 160 161 print = (*np) > 0; 162 163 for (; hp != 0; hp = hp->Hnext) { 164 (*np)--; 165 hp->Href++; 166 if (rflg == 0) { 167 dohist1(hp->Hnext, np, rflg, hflg); 168 if (print) 169 phist(hp, hflg); 170 return; 171 } 172 if (*np >= 0) 173 phist(hp, hflg); 174 } 175 } 176 177 static void 178 phist(struct Hist *hp, int hflg) 179 { 180 if (hflg == 0) 181 (void)fprintf(cshout, "%6d\t", hp->Hnum); 182 prlex(cshout, &hp->Hlex); 183 } 184