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