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