1 /*- 2 * Copyright (c) 1980, 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)hist.c 5.10 (Berkeley) 07/19/91"; 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;) 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 99 if (getn(value(STRhistory)) == 0) 100 return; 101 if (setintr) 102 (void) sigsetmask(sigblock((sigset_t) 0) & ~sigmask(SIGINT)); 103 while (*++v && **v == '-') { 104 Char *vp = *v; 105 106 while (*++vp) 107 switch (*vp) { 108 case 'h': 109 hflg++; 110 break; 111 case 'r': 112 rflg++; 113 break; 114 case '-': /* ignore multiple '-'s */ 115 break; 116 default: 117 stderror(ERR_HISTUS); 118 break; 119 } 120 } 121 if (*v) 122 n = getn(*v); 123 else { 124 n = getn(value(STRhistory)); 125 } 126 dohist1(Histlist.Hnext, &n, rflg, hflg); 127 } 128 129 static void 130 dohist1(hp, np, rflg, hflg) 131 struct Hist *hp; 132 int *np, rflg, hflg; 133 { 134 bool print = (*np) > 0; 135 136 for (; hp != 0; hp = hp->Hnext) { 137 (*np)--; 138 hp->Href++; 139 if (rflg == 0) { 140 dohist1(hp->Hnext, np, rflg, hflg); 141 if (print) 142 phist(hp, hflg); 143 return; 144 } 145 if (*np >= 0) 146 phist(hp, hflg); 147 } 148 } 149 150 static void 151 phist(hp, hflg) 152 register struct Hist *hp; 153 int hflg; 154 { 155 if (hflg == 0) 156 (void) fprintf(cshout, "%6d\t", hp->Hnum); 157 prlex(cshout, &hp->Hlex); 158 } 159