1/* $NetBSD: hist.c,v 1.22 2019/01/05 16:54:00 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 35static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 5/31/93"; 36#else 37__RCSID("$NetBSD: hist.c,v 1.22 2019/01/05 16:54:00 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 49static void hfree(struct Hist *); 50static void dohist1(struct Hist *, int *, int, int); 51static void phist(struct Hist *, int); 52 53void 54savehist(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#ifdef EDIT 86void 87loadhist(struct Hist *hp) { 88 char *h = NULL; 89 90 if (hi == NULL || hp == NULL) 91 return; 92 loadhist(hp->Hnext); 93 if (sprlex(&h, &hp->Hlex) != -1) { 94 HistEvent ev; 95 history(hi, &ev, H_ENTER, h); 96 } 97} 98#endif 99 100struct Hist * 101enthist(int event, struct wordent *lp, int docopy) 102{ 103 struct Hist *np; 104 105#ifdef EDIT 106 if (hi) { 107 char *h = NULL; 108 if (sprlex(&h, lp) != -1) { 109 HistEvent ev; 110 history(hi, &ev, H_ENTER, h); 111 } 112 } 113#endif 114 np = xmalloc(sizeof(*np)); 115 np->Hnum = np->Href = event; 116 if (docopy) { 117 copylex(&np->Hlex, lp); 118 } 119 else { 120 np->Hlex.next = lp->next; 121 lp->next->prev = &np->Hlex; 122 np->Hlex.prev = lp->prev; 123 lp->prev->next = &np->Hlex; 124 } 125 np->Hnext = Histlist.Hnext; 126 Histlist.Hnext = np; 127 return (np); 128} 129 130static void 131hfree(struct Hist *hp) 132{ 133 freelex(&hp->Hlex); 134 free(hp); 135} 136 137void 138/*ARGSUSED*/ 139dohist(Char **v, struct command *t) 140{ 141 sigset_t nsigset; 142 int hflg, n, rflg; 143 144 hflg = 0; 145 rflg = 0; 146 147 if (getn(value(STRhistory)) == 0) 148 return; 149 if (setintr) { 150 sigemptyset(&nsigset); 151 (void)sigaddset(&nsigset, SIGINT); 152 (void)sigprocmask(SIG_UNBLOCK, &nsigset, NULL); 153 } 154 while (*++v && **v == '-') { 155 Char *vp = *v; 156 157 while (*++vp) 158 switch (*vp) { 159 case 'h': 160 hflg++; 161 break; 162 case 'r': 163 rflg++; 164 break; 165 case '-': /* ignore multiple '-'s */ 166 break; 167 default: 168 stderror(ERR_HISTUS); 169 /* NOTREACHED */ 170 } 171 } 172 if (*v) 173 n = getn(*v); 174 else { 175 n = getn(value(STRhistory)); 176 } 177 dohist1(Histlist.Hnext, &n, rflg, hflg); 178} 179 180static void 181dohist1(struct Hist *hp, int *np, int rflg, int hflg) 182{ 183 int print; 184 185 print = (*np) > 0; 186 187 for (; hp != 0; hp = hp->Hnext) { 188 (*np)--; 189 hp->Href++; 190 if (rflg == 0) { 191 dohist1(hp->Hnext, np, rflg, hflg); 192 if (print) 193 phist(hp, hflg); 194 return; 195 } 196 if (*np >= 0) 197 phist(hp, hflg); 198 } 199} 200 201static void 202phist(struct Hist *hp, int hflg) 203{ 204 if (hflg == 0) 205 (void)fprintf(cshout, "%6d\t", hp->Hnum); 206 prlex(cshout, &hp->Hlex); 207} 208