1 /*- 2 * Copyright (c) 1980, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 /*static char sccsid[] = "from: @(#)hist.c 8.1 (Berkeley) 5/31/93";*/ 36 static char *rcsid = "$Id: hist.c,v 1.5 1994/09/21 00:10:58 mycroft Exp $"; 37 #endif /* not lint */ 38 39 #include <sys/types.h> 40 #include <stdlib.h> 41 #if __STDC__ 42 # include <stdarg.h> 43 #else 44 # include <varargs.h> 45 #endif 46 47 #include "csh.h" 48 #include "extern.h" 49 50 static void hfree __P((struct Hist *)); 51 static void dohist1 __P((struct Hist *, int *, int, int)); 52 static void phist __P((struct Hist *, int)); 53 54 void 55 savehist(sp) 56 struct wordent *sp; 57 { 58 register struct Hist *hp, *np; 59 register int histlen = 0; 60 Char *cp; 61 62 /* throw away null lines */ 63 if (sp->next->word[0] == '\n') 64 return; 65 cp = value(STRhistory); 66 if (*cp) { 67 register 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(event, lp, docopy) 87 int event; 88 register struct wordent *lp; 89 bool docopy; 90 { 91 register struct Hist *np; 92 93 np = (struct Hist *) xmalloc((size_t) sizeof(*np)); 94 np->Hnum = np->Href = event; 95 if (docopy) { 96 copylex(&np->Hlex, lp); 97 } 98 else { 99 np->Hlex.next = lp->next; 100 lp->next->prev = &np->Hlex; 101 np->Hlex.prev = lp->prev; 102 lp->prev->next = &np->Hlex; 103 } 104 np->Hnext = Histlist.Hnext; 105 Histlist.Hnext = np; 106 return (np); 107 } 108 109 static void 110 hfree(hp) 111 register struct Hist *hp; 112 { 113 114 freelex(&hp->Hlex); 115 xfree((ptr_t) hp); 116 } 117 118 void 119 /*ARGSUSED*/ 120 dohist(v, t) 121 Char **v; 122 struct command *t; 123 { 124 int n, rflg = 0, hflg = 0; 125 126 if (getn(value(STRhistory)) == 0) 127 return; 128 if (setintr) 129 (void) sigsetmask(sigblock((sigset_t) 0) & ~sigmask(SIGINT)); 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 break; 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(hp, np, rflg, hflg) 158 struct Hist *hp; 159 int *np, rflg, hflg; 160 { 161 bool 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(hp, hflg) 179 register struct Hist *hp; 180 int hflg; 181 { 182 if (hflg == 0) 183 (void) fprintf(cshout, "%6d\t", hp->Hnum); 184 prlex(cshout, &hp->Hlex); 185 } 186