hist.c revision 1.4 1 /*-
2 * Copyright (c) 1980, 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #ifndef lint
35 /*static char sccsid[] = "from: @(#)hist.c 5.9 (Berkeley) 6/8/91";*/
36 static char rcsid[] = "$Id: hist.c,v 1.4 1993/08/01 19:00:40 mycroft Exp $";
37 #endif /* not lint */
38
39 #include <sys/types.h>
40 #include <stdlib.h>
41 #if __STDC__
42 # include <stdarg.h>
43 #else
44 # include <varargs.h>
45 #endif
46
47 #include "csh.h"
48 #include "extern.h"
49
50 static void hfree __P((struct Hist *));
51 static void dohist1 __P((struct Hist *, int *, int, int, int));
52 static void phist __P((struct Hist *, int, int));
53
54 void
55 savehist(sp)
56 struct wordent *sp;
57 {
58 register struct Hist *hp, *np;
59 register int histlen = 0;
60 Char *cp;
61
62 /* throw away null lines */
63 if (sp->next->word[0] == '\n')
64 return;
65 cp = value(STRhistory);
66 if (*cp) {
67 register Char *p = cp;
68
69 while (*p) {
70 if (!Isdigit(*p)) {
71 histlen = 0;
72 break;
73 }
74 histlen = histlen * 10 + *p++ - '0';
75 }
76 }
77 for (hp = &Histlist; np = hp->Hnext;)
78 if (eventno - np->Href >= histlen || histlen == 0)
79 hp->Hnext = np->Hnext, hfree(np);
80 else
81 hp = np;
82 (void) enthist(++eventno, sp, 1);
83 }
84
85 struct Hist *
86 enthist(event, lp, docopy)
87 int event;
88 register struct wordent *lp;
89 bool docopy;
90 {
91 register struct Hist *np;
92
93 np = (struct Hist *) xmalloc((size_t) sizeof(*np));
94 (void) time(&(np->Htime));
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(hp)
112 register struct Hist *hp;
113 {
114
115 freelex(&hp->Hlex);
116 xfree((ptr_t) hp);
117 }
118
119 void
120 dohist(vp)
121 Char **vp;
122 {
123 int n, rflg = 0, hflg = 0, tflg = 0;
124
125 if (getn(value(STRhistory)) == 0)
126 return;
127 if (setintr)
128 (void) sigsetmask(sigblock((sigset_t) 0) & ~sigmask(SIGINT));
129 while (*++vp && **vp == '-') {
130 Char *vp2 = *vp;
131
132 while (*++vp2)
133 switch (*vp2) {
134 case 'h':
135 hflg++;
136 break;
137 case 'r':
138 rflg++;
139 break;
140 case 't':
141 tflg++;
142 break;
143 case '-': /* ignore multiple '-'s */
144 break;
145 default:
146 stderror(ERR_HISTUS);
147 break;
148 }
149 }
150 if (*vp)
151 n = getn(*vp);
152 else {
153 n = getn(value(STRhistory));
154 }
155 dohist1(Histlist.Hnext, &n, rflg, hflg, tflg);
156 }
157
158 static void
159 dohist1(hp, np, rflg, hflg, tflg)
160 struct Hist *hp;
161 int *np, rflg, hflg, tflg;
162 {
163 bool print = (*np) > 0;
164
165 for (; hp != 0; hp = hp->Hnext) {
166 (*np)--;
167 hp->Href++;
168 if (rflg == 0) {
169 dohist1(hp->Hnext, np, rflg, hflg, tflg);
170 if (print)
171 phist(hp, hflg, tflg);
172 return;
173 }
174 if (*np >= 0)
175 phist(hp, hflg, tflg);
176 }
177 }
178
179 static void
180 phist(hp, hflg, tflg)
181 register struct Hist *hp;
182 int hflg, tflg;
183 {
184 struct tm *t;
185 char ampm = 'a';
186
187 if (hflg == 0) {
188 xprintf("%6d\t", hp->Hnum);
189 if (tflg == 0) {
190 t = localtime(&hp->Htime);
191 if (adrof(STRampm)) { /* addition by Hans J. Albertsson */
192 if (t->tm_hour >= 12) {
193 if (t->tm_hour > 12)
194 t->tm_hour -= 12;
195 ampm = 'p';
196 }
197 else if (t->tm_hour == 0)
198 t->tm_hour = 12;
199 xprintf("%2d:%02d%cm\t", t->tm_hour, t->tm_min, ampm);
200 }
201 else {
202 xprintf("%2d:%02d\t", t->tm_hour, t->tm_min);
203 }
204 }
205 }
206 prlex(&hp->Hlex);
207 }
208