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