xref: /csrg-svn/bin/csh/hist.c (revision 68576)
147823Sbostic /*-
260765Sbostic  * Copyright (c) 1980, 1991, 1993
360765Sbostic  *	The Regents of the University of California.  All rights reserved.
447823Sbostic  *
547823Sbostic  * %sccs.include.redist.c%
621935Sdist  */
721935Sdist 
817509Sedward #ifndef lint
9*68576Schristos static char sccsid[] = "@(#)hist.c	8.2 (Berkeley) 03/22/95";
1047823Sbostic #endif /* not lint */
111297Sbill 
1250028Sbostic #include <sys/types.h>
1350028Sbostic #include <stdlib.h>
1450033Schristos #if __STDC__
1550033Schristos # include <stdarg.h>
1650033Schristos #else
1750033Schristos # include <varargs.h>
1850033Schristos #endif
1950033Schristos 
2050023Sbostic #include "csh.h"
2150023Sbostic #include "extern.h"
221297Sbill 
2350024Schristos static void	hfree __P((struct Hist *));
2450439Schristos static void	dohist1 __P((struct Hist *, int *, int, int));
2550439Schristos static void	phist __P((struct Hist *, int));
261297Sbill 
2749992Sbostic void
savehist(sp)281297Sbill savehist(sp)
2949992Sbostic     struct wordent *sp;
301297Sbill {
3149992Sbostic     register struct Hist *hp, *np;
3249992Sbostic     register int histlen = 0;
3349992Sbostic     Char   *cp;
341297Sbill 
3549992Sbostic     /* throw away null lines */
3649992Sbostic     if (sp->next->word[0] == '\n')
3749992Sbostic 	return;
3849992Sbostic     cp = value(STRhistory);
3949992Sbostic     if (*cp) {
4049992Sbostic 	register Char *p = cp;
4117509Sedward 
4249992Sbostic 	while (*p) {
4349992Sbostic 	    if (!Isdigit(*p)) {
4449992Sbostic 		histlen = 0;
4549992Sbostic 		break;
4649992Sbostic 	    }
4749992Sbostic 	    histlen = histlen * 10 + *p++ - '0';
4817509Sedward 	}
4949992Sbostic     }
5060237Schristos     for (hp = &Histlist; (np = hp->Hnext) != NULL;)
5149992Sbostic 	if (eventno - np->Href >= histlen || histlen == 0)
5249992Sbostic 	    hp->Hnext = np->Hnext, hfree(np);
5349992Sbostic 	else
5449992Sbostic 	    hp = np;
5549992Sbostic     (void) enthist(++eventno, sp, 1);
561297Sbill }
571297Sbill 
581297Sbill struct Hist *
enthist(event,lp,docopy)591297Sbill enthist(event, lp, docopy)
6049992Sbostic     int     event;
6149992Sbostic     register struct wordent *lp;
6249992Sbostic     bool    docopy;
631297Sbill {
6449992Sbostic     register struct Hist *np;
651297Sbill 
6649992Sbostic     np = (struct Hist *) xmalloc((size_t) sizeof(*np));
6749992Sbostic     np->Hnum = np->Href = event;
6849992Sbostic     if (docopy) {
6949992Sbostic 	copylex(&np->Hlex, lp);
7049992Sbostic     }
7149992Sbostic     else {
7249992Sbostic 	np->Hlex.next = lp->next;
7349992Sbostic 	lp->next->prev = &np->Hlex;
7449992Sbostic 	np->Hlex.prev = lp->prev;
7549992Sbostic 	lp->prev->next = &np->Hlex;
7649992Sbostic     }
7749992Sbostic     np->Hnext = Histlist.Hnext;
7849992Sbostic     Histlist.Hnext = np;
7949992Sbostic     return (np);
801297Sbill }
811297Sbill 
8249992Sbostic static void
hfree(hp)831297Sbill hfree(hp)
8449992Sbostic     register struct Hist *hp;
851297Sbill {
861297Sbill 
8749992Sbostic     freelex(&hp->Hlex);
8849992Sbostic     xfree((ptr_t) hp);
891297Sbill }
901297Sbill 
9149992Sbostic void
9250439Schristos /*ARGSUSED*/
dohist(v,t)9350439Schristos dohist(v, t)
9450439Schristos     Char **v;
9550439Schristos     struct command *t;
961297Sbill {
9750439Schristos     int     n, rflg = 0, hflg = 0;
98*68576Schristos     sigset_t sigset;
9949992Sbostic 
10049992Sbostic     if (getn(value(STRhistory)) == 0)
10149992Sbostic 	return;
102*68576Schristos     if (setintr) {
103*68576Schristos 	sigemptyset(&sigset);
104*68576Schristos 	sigaddset(&sigset, SIGINT);
105*68576Schristos 	sigprocmask(SIG_UNBLOCK, &sigset, NULL);
106*68576Schristos     }
10750439Schristos     while (*++v && **v == '-') {
10850439Schristos 	Char   *vp = *v;
10949992Sbostic 
11050439Schristos 	while (*++vp)
11150439Schristos 	    switch (*vp) {
11249992Sbostic 	    case 'h':
11349992Sbostic 		hflg++;
11449992Sbostic 		break;
11549992Sbostic 	    case 'r':
11649992Sbostic 		rflg++;
11749992Sbostic 		break;
11849992Sbostic 	    case '-':		/* ignore multiple '-'s */
11949992Sbostic 		break;
12049992Sbostic 	    default:
12149992Sbostic 		stderror(ERR_HISTUS);
12249992Sbostic 		break;
12349992Sbostic 	    }
12449992Sbostic     }
12550439Schristos     if (*v)
12650439Schristos 	n = getn(*v);
12749992Sbostic     else {
12849992Sbostic 	n = getn(value(STRhistory));
12949992Sbostic     }
13050439Schristos     dohist1(Histlist.Hnext, &n, rflg, hflg);
1311297Sbill }
1321297Sbill 
13349992Sbostic static void
dohist1(hp,np,rflg,hflg)13450439Schristos dohist1(hp, np, rflg, hflg)
13549992Sbostic     struct Hist *hp;
13650439Schristos     int    *np, rflg, hflg;
1371297Sbill {
13849992Sbostic     bool    print = (*np) > 0;
13949992Sbostic 
14049992Sbostic     for (; hp != 0; hp = hp->Hnext) {
1411297Sbill 	(*np)--;
1421297Sbill 	hp->Href++;
1431297Sbill 	if (rflg == 0) {
14450439Schristos 	    dohist1(hp->Hnext, np, rflg, hflg);
14549992Sbostic 	    if (print)
14650439Schristos 		phist(hp, hflg);
14749992Sbostic 	    return;
1481297Sbill 	}
1491297Sbill 	if (*np >= 0)
15050439Schristos 	    phist(hp, hflg);
15149992Sbostic     }
1521297Sbill }
1531297Sbill 
15449992Sbostic static void
phist(hp,hflg)15550439Schristos phist(hp, hflg)
15649992Sbostic     register struct Hist *hp;
15750439Schristos     int     hflg;
1581297Sbill {
15950439Schristos     if (hflg == 0)
16050439Schristos 	(void) fprintf(cshout, "%6d\t", hp->Hnum);
16150439Schristos     prlex(cshout, &hp->Hlex);
1621297Sbill }
163