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