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