xref: /illumos-gate/usr/src/cmd/csh/sh.hist.c (revision f3682895b2a97c009685f16e8a4e5d3dc80e11f2)
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
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 *
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
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
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
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
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