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