hist.c revision 1.12 1 /* $NetBSD: hist.c,v 1.12 2001/09/14 14:04:00 wiz 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.12 2001/09/14 14:04:00 wiz Exp $");
42 #endif
43 #endif /* not lint */
44
45 #include <sys/types.h>
46
47 #include <stdlib.h>
48
49 #if __STDC__
50 # include <stdarg.h>
51 #else
52 # include <varargs.h>
53 #endif
54
55 #include "csh.h"
56 #include "extern.h"
57
58 static void hfree(struct Hist *);
59 static void dohist1(struct Hist *, int *, int, int);
60 static void phist(struct Hist *, int);
61
62 void
63 savehist(struct wordent *sp)
64 {
65 struct Hist *hp, *np;
66 Char *cp;
67 int histlen;
68
69 histlen = 0;
70
71 /* throw away null lines */
72 if (sp->next->word[0] == '\n')
73 return;
74 cp = value(STRhistory);
75 if (*cp) {
76 Char *p = cp;
77
78 while (*p) {
79 if (!Isdigit(*p)) {
80 histlen = 0;
81 break;
82 }
83 histlen = histlen * 10 + *p++ - '0';
84 }
85 }
86 for (hp = &Histlist; (np = hp->Hnext) != NULL;)
87 if (eventno - np->Href >= histlen || histlen == 0)
88 hp->Hnext = np->Hnext, hfree(np);
89 else
90 hp = np;
91 (void) enthist(++eventno, sp, 1);
92 }
93
94 struct Hist *
95 enthist(int event, struct wordent *lp, 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(struct Hist *hp)
117 {
118 freelex(&hp->Hlex);
119 xfree((ptr_t) hp);
120 }
121
122 void
123 /*ARGSUSED*/
124 dohist(Char **v, struct command *t)
125 {
126 sigset_t sigset;
127 int hflg, n, rflg;
128
129 hflg = 0;
130 rflg = 0;
131
132 if (getn(value(STRhistory)) == 0)
133 return;
134 if (setintr) {
135 sigemptyset(&sigset);
136 (void)sigaddset(&sigset, SIGINT);
137 (void)sigprocmask(SIG_UNBLOCK, &sigset, NULL);
138 }
139 while (*++v && **v == '-') {
140 Char *vp = *v;
141
142 while (*++vp)
143 switch (*vp) {
144 case 'h':
145 hflg++;
146 break;
147 case 'r':
148 rflg++;
149 break;
150 case '-': /* ignore multiple '-'s */
151 break;
152 default:
153 stderror(ERR_HISTUS);
154 /* NOTREACHED */
155 }
156 }
157 if (*v)
158 n = getn(*v);
159 else {
160 n = getn(value(STRhistory));
161 }
162 dohist1(Histlist.Hnext, &n, rflg, hflg);
163 }
164
165 static void
166 dohist1(struct Hist *hp, int *np, int rflg, int hflg)
167 {
168 bool print;
169
170 print = (*np) > 0;
171
172 for (; hp != 0; hp = hp->Hnext) {
173 (*np)--;
174 hp->Href++;
175 if (rflg == 0) {
176 dohist1(hp->Hnext, np, rflg, hflg);
177 if (print)
178 phist(hp, hflg);
179 return;
180 }
181 if (*np >= 0)
182 phist(hp, hflg);
183 }
184 }
185
186 static void
187 phist(struct Hist *hp, int hflg)
188 {
189 if (hflg == 0)
190 (void)fprintf(cshout, "%6d\t", hp->Hnum);
191 prlex(cshout, &hp->Hlex);
192 }
193