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 40static void hfree(struct Hist *); 41static void dohist1(struct Hist *, int *, int, int); 42static void phist(struct Hist *, int); 43 44void 45savehist(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 74struct Hist * 75enthist(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 95static void 96hfree(struct Hist *hp) 97{ 98 99 freelex(&hp->Hlex); 100 free(hp); 101} 102 103void 104dohist(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 142static void 143dohist1(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 161static void 162phist(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