hist.c revision 1.11 1 /* $NetBSD: hist.c,v 1.11 1998/07/28 02:47:20 mycroft 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. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include <sys/cdefs.h>
37 #ifndef lint
38 #if 0
39 static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 5/31/93";
40 #else
41 __RCSID("$NetBSD: hist.c,v 1.11 1998/07/28 02:47:20 mycroft Exp $");
42 #endif
43 #endif /* not lint */
44
45 #include <sys/types.h>
46 #include <stdlib.h>
47 #if __STDC__
48 # include <stdarg.h>
49 #else
50 # include <varargs.h>
51 #endif
52
53 #include "csh.h"
54 #include "extern.h"
55
56 static void hfree __P((struct Hist *));
57 static void dohist1 __P((struct Hist *, int *, int, int));
58 static void phist __P((struct Hist *, int));
59
60 void
61 savehist(sp)
62 struct wordent *sp;
63 {
64 struct Hist *hp, *np;
65 int histlen = 0;
66 Char *cp;
67
68 /* throw away null lines */
69 if (sp->next->word[0] == '\n')
70 return;
71 cp = value(STRhistory);
72 if (*cp) {
73 Char *p = cp;
74
75 while (*p) {
76 if (!Isdigit(*p)) {
77 histlen = 0;
78 break;
79 }
80 histlen = histlen * 10 + *p++ - '0';
81 }
82 }
83 for (hp = &Histlist; (np = hp->Hnext) != NULL;)
84 if (eventno - np->Href >= histlen || histlen == 0)
85 hp->Hnext = np->Hnext, hfree(np);
86 else
87 hp = np;
88 (void) enthist(++eventno, sp, 1);
89 }
90
91 struct Hist *
92 enthist(event, lp, docopy)
93 int event;
94 struct wordent *lp;
95 bool docopy;
96 {
97 struct Hist *np;
98
99 np = (struct Hist *) xmalloc((size_t) sizeof(*np));
100 np->Hnum = np->Href = event;
101 if (docopy) {
102 copylex(&np->Hlex, lp);
103 }
104 else {
105 np->Hlex.next = lp->next;
106 lp->next->prev = &np->Hlex;
107 np->Hlex.prev = lp->prev;
108 lp->prev->next = &np->Hlex;
109 }
110 np->Hnext = Histlist.Hnext;
111 Histlist.Hnext = np;
112 return (np);
113 }
114
115 static void
116 hfree(hp)
117 struct Hist *hp;
118 {
119
120 freelex(&hp->Hlex);
121 xfree((ptr_t) hp);
122 }
123
124 void
125 /*ARGSUSED*/
126 dohist(v, t)
127 Char **v;
128 struct command *t;
129 {
130 int n, rflg = 0, hflg = 0;
131 sigset_t sigset;
132
133 if (getn(value(STRhistory)) == 0)
134 return;
135 if (setintr) {
136 sigemptyset(&sigset);
137 (void) sigaddset(&sigset, SIGINT);
138 (void) sigprocmask(SIG_UNBLOCK, &sigset, NULL);
139 }
140 while (*++v && **v == '-') {
141 Char *vp = *v;
142
143 while (*++vp)
144 switch (*vp) {
145 case 'h':
146 hflg++;
147 break;
148 case 'r':
149 rflg++;
150 break;
151 case '-': /* ignore multiple '-'s */
152 break;
153 default:
154 stderror(ERR_HISTUS);
155 /* NOTREACHED */
156 }
157 }
158 if (*v)
159 n = getn(*v);
160 else {
161 n = getn(value(STRhistory));
162 }
163 dohist1(Histlist.Hnext, &n, rflg, hflg);
164 }
165
166 static void
167 dohist1(hp, np, rflg, hflg)
168 struct Hist *hp;
169 int *np, rflg, hflg;
170 {
171 bool print = (*np) > 0;
172
173 for (; hp != 0; hp = hp->Hnext) {
174 (*np)--;
175 hp->Href++;
176 if (rflg == 0) {
177 dohist1(hp->Hnext, np, rflg, hflg);
178 if (print)
179 phist(hp, hflg);
180 return;
181 }
182 if (*np >= 0)
183 phist(hp, hflg);
184 }
185 }
186
187 static void
188 phist(hp, hflg)
189 struct Hist *hp;
190 int hflg;
191 {
192 if (hflg == 0)
193 (void) fprintf(cshout, "%6d\t", hp->Hnum);
194 prlex(cshout, &hp->Hlex);
195 }
196