1 /*- 2 * Copyright (c) 1980, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)hist.c 8.2 (Berkeley) 03/22/95"; 10 #endif /* not lint */ 11 12 #include <sys/types.h> 13 #include <stdlib.h> 14 #if __STDC__ 15 # include <stdarg.h> 16 #else 17 # include <varargs.h> 18 #endif 19 20 #include "csh.h" 21 #include "extern.h" 22 23 static void hfree __P((struct Hist *)); 24 static void dohist1 __P((struct Hist *, int *, int, int)); 25 static void phist __P((struct Hist *, int)); 26 27 void 28 savehist(sp) 29 struct wordent *sp; 30 { 31 register struct Hist *hp, *np; 32 register int histlen = 0; 33 Char *cp; 34 35 /* throw away null lines */ 36 if (sp->next->word[0] == '\n') 37 return; 38 cp = value(STRhistory); 39 if (*cp) { 40 register Char *p = cp; 41 42 while (*p) { 43 if (!Isdigit(*p)) { 44 histlen = 0; 45 break; 46 } 47 histlen = histlen * 10 + *p++ - '0'; 48 } 49 } 50 for (hp = &Histlist; (np = hp->Hnext) != NULL;) 51 if (eventno - np->Href >= histlen || histlen == 0) 52 hp->Hnext = np->Hnext, hfree(np); 53 else 54 hp = np; 55 (void) enthist(++eventno, sp, 1); 56 } 57 58 struct Hist * 59 enthist(event, lp, docopy) 60 int event; 61 register struct wordent *lp; 62 bool docopy; 63 { 64 register struct Hist *np; 65 66 np = (struct Hist *) xmalloc((size_t) sizeof(*np)); 67 np->Hnum = np->Href = event; 68 if (docopy) { 69 copylex(&np->Hlex, lp); 70 } 71 else { 72 np->Hlex.next = lp->next; 73 lp->next->prev = &np->Hlex; 74 np->Hlex.prev = lp->prev; 75 lp->prev->next = &np->Hlex; 76 } 77 np->Hnext = Histlist.Hnext; 78 Histlist.Hnext = np; 79 return (np); 80 } 81 82 static void 83 hfree(hp) 84 register struct Hist *hp; 85 { 86 87 freelex(&hp->Hlex); 88 xfree((ptr_t) hp); 89 } 90 91 void 92 /*ARGSUSED*/ 93 dohist(v, t) 94 Char **v; 95 struct command *t; 96 { 97 int n, rflg = 0, hflg = 0; 98 sigset_t sigset; 99 100 if (getn(value(STRhistory)) == 0) 101 return; 102 if (setintr) { 103 sigemptyset(&sigset); 104 sigaddset(&sigset, SIGINT); 105 sigprocmask(SIG_UNBLOCK, &sigset, NULL); 106 } 107 while (*++v && **v == '-') { 108 Char *vp = *v; 109 110 while (*++vp) 111 switch (*vp) { 112 case 'h': 113 hflg++; 114 break; 115 case 'r': 116 rflg++; 117 break; 118 case '-': /* ignore multiple '-'s */ 119 break; 120 default: 121 stderror(ERR_HISTUS); 122 break; 123 } 124 } 125 if (*v) 126 n = getn(*v); 127 else { 128 n = getn(value(STRhistory)); 129 } 130 dohist1(Histlist.Hnext, &n, rflg, hflg); 131 } 132 133 static void 134 dohist1(hp, np, rflg, hflg) 135 struct Hist *hp; 136 int *np, rflg, hflg; 137 { 138 bool print = (*np) > 0; 139 140 for (; hp != 0; hp = hp->Hnext) { 141 (*np)--; 142 hp->Href++; 143 if (rflg == 0) { 144 dohist1(hp->Hnext, np, rflg, hflg); 145 if (print) 146 phist(hp, hflg); 147 return; 148 } 149 if (*np >= 0) 150 phist(hp, hflg); 151 } 152 } 153 154 static void 155 phist(hp, hflg) 156 register struct Hist *hp; 157 int hflg; 158 { 159 if (hflg == 0) 160 (void) fprintf(cshout, "%6d\t", hp->Hnum); 161 prlex(cshout, &hp->Hlex); 162 } 163