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
savehist(sp)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 *
enthist(event,lp,docopy)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
hfree(hp)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*/
dohist(v,t)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
dohist1(hp,np,rflg,hflg)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
phist(hp,hflg)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