1 /*
2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
8
9 /*
10 * Copyright (c) 1980 Regents of the University of California.
11 * All rights reserved. The Berkeley Software License Agreement
12 * specifies the terms and conditions for redistribution.
13 */
14
15 #include "sh.h"
16 #include "sh.tconst.h"
17
18 struct Hist Histlist;
19 int eventno;
20
21 struct Hist *enthist(int, struct wordent *, bool);
22 void hfree(struct Hist *);
23 void dohist1(struct Hist *, int *, int, int);
24 void phist(struct Hist *, int);
25
26 /*
27 * C shell
28 */
29
30 void
savehist(struct wordent * sp)31 savehist(struct wordent *sp)
32 {
33 struct Hist *hp, *np;
34 int histlen = 0;
35 tchar *cp;
36
37 #ifdef TRACE
38 tprintf("TRACE- savehist()\n");
39 #endif
40 /* throw away null lines */
41 if (sp->next->word[0] == '\n')
42 return;
43 cp = value(S_history /*"history"*/);
44 if (*cp) {
45 tchar *p = cp;
46
47 while (*p) {
48 if (!digit(*p)) {
49 histlen = 0;
50 break;
51 }
52 histlen = histlen * 10 + *p++ - '0';
53 }
54 }
55 for (hp = &Histlist; np = hp->Hnext;)
56 if (eventno - np->Href >= histlen || histlen == 0)
57 hp->Hnext = np->Hnext, hfree(np);
58 else
59 hp = np;
60 (void) enthist(++eventno, sp, 1);
61 }
62
63 struct Hist *
enthist(int event,struct wordent * lp,bool docopy)64 enthist(int event, struct wordent *lp, bool docopy)
65 {
66 struct Hist *np;
67
68 #ifdef TRACE
69 tprintf("TRACE- enthist()\n");
70 #endif
71 np = (struct Hist *) xalloc(sizeof *np);
72 np->Hnum = np->Href = event;
73 if (docopy)
74 copylex(&np->Hlex, lp);
75 else {
76 np->Hlex.next = lp->next;
77 lp->next->prev = &np->Hlex;
78 np->Hlex.prev = lp->prev;
79 lp->prev->next = &np->Hlex;
80 }
81 np->Hnext = Histlist.Hnext;
82 Histlist.Hnext = np;
83 return (np);
84 }
85
86 void
hfree(struct Hist * hp)87 hfree(struct Hist *hp)
88 {
89 #ifdef TRACE
90 tprintf("TRACE- hfree()\n");
91 #endif
92
93 freelex(&hp->Hlex);
94 xfree( (tchar *)hp);
95 }
96
97 void
dohist(tchar ** vp)98 dohist(tchar **vp)
99 {
100 int n, rflg = 0, hflg = 0;
101 #ifdef TRACE
102 tprintf("TRACE- dohist()\n");
103 #endif
104 if (getn(value(S_history /*"history"*/)) == 0)
105 return;
106 if (setintr)
107 (void) sigsetmask(sigblock(0) & ~sigmask(SIGINT));
108 while (*++vp && **vp == '-') {
109 tchar *vp2 = *vp;
110
111 while (*++vp2)
112 switch (*vp2) {
113 case 'h':
114 hflg++;
115 break;
116 case 'r':
117 rflg++;
118 break;
119 case '-': /* ignore multiple '-'s */
120 break;
121 default:
122 printf("Unknown flag: -%c\n", *vp2);
123 error("Usage: history [-rh] [# number of events]");
124 }
125 }
126 if (*vp)
127 n = getn(*vp);
128 else {
129 n = getn(value(S_history /*"history"*/));
130 }
131 dohist1(Histlist.Hnext, &n, rflg, hflg);
132 }
133
134 void
dohist1(struct Hist * hp,int * np,int rflg,int hflg)135 dohist1(struct Hist *hp, int *np, int rflg, int hflg)
136 {
137 bool print = (*np) > 0;
138 #ifdef TRACE
139 tprintf("TRACE- dohist1()\n");
140 #endif
141 top:
142 if (hp == 0)
143 return;
144 (*np)--;
145 hp->Href++;
146 if (rflg == 0) {
147 dohist1(hp->Hnext, np, rflg, hflg);
148 if (print)
149 phist(hp, hflg);
150 return;
151 }
152 if (*np >= 0)
153 phist(hp, hflg);
154 hp = hp->Hnext;
155 goto top;
156 }
157
158 void
phist(struct Hist * hp,int hflg)159 phist(struct Hist *hp, int hflg)
160 {
161 #ifdef TRACE
162 tprintf("TRACE- phist()\n");
163 #endif
164
165 if (hflg == 0)
166 printf("%6d\t", hp->Hnum);
167 prlex(&hp->Hlex);
168 }
169