xref: /netbsd-src/bin/csh/hist.c (revision 1767ce60a2fbaa51b3860ae327733a38db5c12f1)
1*1767ce60Schristos /* $NetBSD: hist.c,v 1.22 2019/01/05 16:54:00 christos Exp $ */
249f0ad86Scgd 
361f28255Scgd /*-
4cee2bad8Smycroft  * Copyright (c) 1980, 1991, 1993
5cee2bad8Smycroft  *	The Regents of the University of California.  All rights reserved.
661f28255Scgd  *
761f28255Scgd  * Redistribution and use in source and binary forms, with or without
861f28255Scgd  * modification, are permitted provided that the following conditions
961f28255Scgd  * are met:
1061f28255Scgd  * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd  *    notice, this list of conditions and the following disclaimer.
1261f28255Scgd  * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd  *    notice, this list of conditions and the following disclaimer in the
1461f28255Scgd  *    documentation and/or other materials provided with the distribution.
15b5b29542Sagc  * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd  *    may be used to endorse or promote products derived from this software
1761f28255Scgd  *    without specific prior written permission.
1861f28255Scgd  *
1961f28255Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd  * SUCH DAMAGE.
3061f28255Scgd  */
3161f28255Scgd 
328ea378c6Schristos #include <sys/cdefs.h>
3361f28255Scgd #ifndef lint
3449f0ad86Scgd #if 0
3549f0ad86Scgd static char sccsid[] = "@(#)hist.c	8.1 (Berkeley) 5/31/93";
3649f0ad86Scgd #else
37*1767ce60Schristos __RCSID("$NetBSD: hist.c,v 1.22 2019/01/05 16:54:00 christos Exp $");
3849f0ad86Scgd #endif
3961f28255Scgd #endif /* not lint */
4061f28255Scgd 
4161f28255Scgd #include <sys/types.h>
42b771e65bSwiz 
4361f28255Scgd #include <stdarg.h>
4418158540Swiz #include <stdlib.h>
4561f28255Scgd 
4661f28255Scgd #include "csh.h"
4761f28255Scgd #include "extern.h"
4861f28255Scgd 
49b771e65bSwiz static void hfree(struct Hist *);
50b771e65bSwiz static void dohist1(struct Hist *, int *, int, int);
51b771e65bSwiz static void phist(struct Hist *, int);
5261f28255Scgd 
5361f28255Scgd void
savehist(struct wordent * sp)54b771e65bSwiz savehist(struct wordent *sp)
5561f28255Scgd {
5676adbe2bStls     struct Hist *hp, *np;
5761f28255Scgd     Char *cp;
58b771e65bSwiz     int histlen;
59b771e65bSwiz 
60b771e65bSwiz     histlen = 0;
6161f28255Scgd 
6261f28255Scgd     /* throw away null lines */
6361f28255Scgd     if (sp->next->word[0] == '\n')
6461f28255Scgd 	return;
6561f28255Scgd     cp = value(STRhistory);
6661f28255Scgd     if (*cp) {
6776adbe2bStls 	Char *p = cp;
6861f28255Scgd 
6961f28255Scgd 	while (*p) {
7061f28255Scgd 	    if (!Isdigit(*p)) {
7161f28255Scgd 		histlen = 0;
7261f28255Scgd 		break;
7361f28255Scgd 	    }
7461f28255Scgd 	    histlen = histlen * 10 + *p++ - '0';
7561f28255Scgd 	}
7661f28255Scgd     }
77cee2bad8Smycroft     for (hp = &Histlist; (np = hp->Hnext) != NULL;)
7861f28255Scgd 	if (eventno - np->Href >= histlen || histlen == 0)
7961f28255Scgd 	    hp->Hnext = np->Hnext, hfree(np);
8061f28255Scgd 	else
8161f28255Scgd 	    hp = np;
8261f28255Scgd     (void) enthist(++eventno, sp, 1);
8361f28255Scgd }
8461f28255Scgd 
8518513677Schristos #ifdef EDIT
8618513677Schristos void
loadhist(struct Hist * hp)8718513677Schristos loadhist(struct Hist *hp) {
8818513677Schristos     char *h = NULL;
8918513677Schristos 
9018513677Schristos     if (hi == NULL || hp == NULL)
9118513677Schristos 	return;
9218513677Schristos     loadhist(hp->Hnext);
9318513677Schristos     if (sprlex(&h, &hp->Hlex) != -1) {
9418513677Schristos 	HistEvent ev;
9518513677Schristos 	history(hi, &ev, H_ENTER, h);
9618513677Schristos     }
9718513677Schristos }
9818513677Schristos #endif
9918513677Schristos 
10061f28255Scgd struct Hist *
enthist(int event,struct wordent * lp,int docopy)101b79c2ef2Schristos enthist(int event, struct wordent *lp, int docopy)
10261f28255Scgd {
10376adbe2bStls     struct Hist *np;
10461f28255Scgd 
10518513677Schristos #ifdef EDIT
10618513677Schristos     if (hi) {
10718513677Schristos 	char *h = NULL;
10818513677Schristos 	if (sprlex(&h, lp) != -1) {
10918513677Schristos 	    HistEvent ev;
11018513677Schristos 	    history(hi, &ev, H_ENTER, h);
11118513677Schristos 	}
11218513677Schristos     }
11318513677Schristos #endif
11437e39248Schristos     np = xmalloc(sizeof(*np));
11561f28255Scgd     np->Hnum = np->Href = event;
11661f28255Scgd     if (docopy) {
11761f28255Scgd 	copylex(&np->Hlex, lp);
11861f28255Scgd     }
11961f28255Scgd     else {
12061f28255Scgd 	np->Hlex.next = lp->next;
12161f28255Scgd 	lp->next->prev = &np->Hlex;
12261f28255Scgd 	np->Hlex.prev = lp->prev;
12361f28255Scgd 	lp->prev->next = &np->Hlex;
12461f28255Scgd     }
12561f28255Scgd     np->Hnext = Histlist.Hnext;
12661f28255Scgd     Histlist.Hnext = np;
12761f28255Scgd     return (np);
12861f28255Scgd }
12961f28255Scgd 
13061f28255Scgd static void
hfree(struct Hist * hp)131b771e65bSwiz hfree(struct Hist *hp)
13261f28255Scgd {
13361f28255Scgd     freelex(&hp->Hlex);
134*1767ce60Schristos     free(hp);
13561f28255Scgd }
13661f28255Scgd 
13761f28255Scgd void
138cee2bad8Smycroft /*ARGSUSED*/
dohist(Char ** v,struct command * t)139b771e65bSwiz dohist(Char **v, struct command *t)
14061f28255Scgd {
141b3df6303Skleink     sigset_t nsigset;
142b771e65bSwiz     int hflg, n, rflg;
143b771e65bSwiz 
144b771e65bSwiz     hflg = 0;
145b771e65bSwiz     rflg = 0;
14661f28255Scgd 
14761f28255Scgd     if (getn(value(STRhistory)) == 0)
14861f28255Scgd 	return;
1497b38403cSmycroft     if (setintr) {
150b3df6303Skleink 	sigemptyset(&nsigset);
151b3df6303Skleink 	(void)sigaddset(&nsigset, SIGINT);
152b3df6303Skleink 	(void)sigprocmask(SIG_UNBLOCK, &nsigset, NULL);
1537b38403cSmycroft     }
154cee2bad8Smycroft     while (*++v && **v == '-') {
155cee2bad8Smycroft 	Char *vp = *v;
15661f28255Scgd 
157cee2bad8Smycroft 	while (*++vp)
158cee2bad8Smycroft 	    switch (*vp) {
15961f28255Scgd 	    case 'h':
16061f28255Scgd 		hflg++;
16161f28255Scgd 		break;
16261f28255Scgd 	    case 'r':
16361f28255Scgd 		rflg++;
16461f28255Scgd 		break;
16561f28255Scgd 	    case '-':		/* ignore multiple '-'s */
16661f28255Scgd 		break;
16761f28255Scgd 	    default:
16861f28255Scgd 		stderror(ERR_HISTUS);
169cdbd74daSmycroft 		/* NOTREACHED */
17061f28255Scgd 	    }
17161f28255Scgd     }
172cee2bad8Smycroft     if (*v)
173cee2bad8Smycroft 	n = getn(*v);
17461f28255Scgd     else {
17561f28255Scgd 	n = getn(value(STRhistory));
17661f28255Scgd     }
177cee2bad8Smycroft     dohist1(Histlist.Hnext, &n, rflg, hflg);
17861f28255Scgd }
17961f28255Scgd 
18061f28255Scgd static void
dohist1(struct Hist * hp,int * np,int rflg,int hflg)181b771e65bSwiz dohist1(struct Hist *hp, int *np, int rflg, int hflg)
18261f28255Scgd {
183b79c2ef2Schristos     int print;
184b771e65bSwiz 
185b771e65bSwiz     print = (*np) > 0;
18661f28255Scgd 
18761f28255Scgd     for (; hp != 0; hp = hp->Hnext) {
18861f28255Scgd 	(*np)--;
18961f28255Scgd 	hp->Href++;
19061f28255Scgd 	if (rflg == 0) {
191cee2bad8Smycroft 	    dohist1(hp->Hnext, np, rflg, hflg);
19261f28255Scgd 	    if (print)
193cee2bad8Smycroft 		phist(hp, hflg);
19461f28255Scgd 	    return;
19561f28255Scgd 	}
19661f28255Scgd 	if (*np >= 0)
197cee2bad8Smycroft 	    phist(hp, hflg);
19861f28255Scgd     }
19961f28255Scgd }
20061f28255Scgd 
20161f28255Scgd static void
phist(struct Hist * hp,int hflg)202b771e65bSwiz phist(struct Hist *hp, int hflg)
20361f28255Scgd {
204cee2bad8Smycroft     if (hflg == 0)
205cee2bad8Smycroft 	(void)fprintf(cshout, "%6d\t", hp->Hnum);
206cee2bad8Smycroft     prlex(cshout, &hp->Hlex);
20761f28255Scgd }
208