1 /* $OpenBSD: hist.c,v 1.10 2015/12/26 13:48:38 mestre 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 /*ARGSUSED*/ 105 dohist(Char **v, struct command *t) 106 { 107 int n, rflg = 0, hflg = 0; 108 sigset_t sigset; 109 110 if (getn(value(STRhistory)) == 0) 111 return; 112 if (setintr) { 113 sigemptyset(&sigset); 114 sigaddset(&sigset, SIGINT); 115 sigprocmask(SIG_UNBLOCK, &sigset, NULL); 116 } 117 while (*++v && **v == '-') { 118 Char *vp = *v; 119 120 while (*++vp) 121 switch (*vp) { 122 case 'h': 123 hflg++; 124 break; 125 case 'r': 126 rflg++; 127 break; 128 case '-': /* ignore multiple '-'s */ 129 break; 130 default: 131 stderror(ERR_HISTUS); 132 break; 133 } 134 } 135 if (*v) 136 n = getn(*v); 137 else { 138 n = getn(value(STRhistory)); 139 } 140 dohist1(Histlist.Hnext, &n, rflg, hflg); 141 } 142 143 static void 144 dohist1(struct Hist *hp, int *np, int rflg, int hflg) 145 { 146 bool print = (*np) > 0; 147 148 for (; hp != 0; hp = hp->Hnext) { 149 (*np)--; 150 hp->Href++; 151 if (rflg == 0) { 152 dohist1(hp->Hnext, np, rflg, hflg); 153 if (print) 154 phist(hp, hflg); 155 return; 156 } 157 if (*np >= 0) 158 phist(hp, hflg); 159 } 160 } 161 162 static void 163 phist(struct Hist *hp, int hflg) 164 { 165 if (hflg == 0) 166 (void) fprintf(cshout, "%6d\t", hp->Hnum); 167 prlex(cshout, &hp->Hlex); 168 } 169