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