1d6fabe6eSbostic /*-
2548b48c4Sbostic * Copyright (c) 1980, 1991, 1993
3548b48c4Sbostic * The Regents of the University of California. All rights reserved.
4d6fabe6eSbostic *
5d6fabe6eSbostic * %sccs.include.redist.c%
6c8c762e4Sdist */
7c8c762e4Sdist
8d60d469cSedward #ifndef lint
9*5fad6ed4Schristos static char sccsid[] = "@(#)hist.c 8.2 (Berkeley) 03/22/95";
10d6fabe6eSbostic #endif /* not lint */
11daa934dcSbill
129374f148Sbostic #include <sys/types.h>
139374f148Sbostic #include <stdlib.h>
14c1ce954aSchristos #if __STDC__
15c1ce954aSchristos # include <stdarg.h>
16c1ce954aSchristos #else
17c1ce954aSchristos # include <varargs.h>
18c1ce954aSchristos #endif
19c1ce954aSchristos
20afc71901Sbostic #include "csh.h"
21afc71901Sbostic #include "extern.h"
22daa934dcSbill
2323ceb1ffSchristos static void hfree __P((struct Hist *));
24cce51c35Schristos static void dohist1 __P((struct Hist *, int *, int, int));
25cce51c35Schristos static void phist __P((struct Hist *, int));
26daa934dcSbill
27f3328da7Sbostic void
savehist(sp)28daa934dcSbill savehist(sp)
29daa934dcSbill struct wordent *sp;
30daa934dcSbill {
31daa934dcSbill register struct Hist *hp, *np;
32d60d469cSedward register int histlen = 0;
33f3328da7Sbostic Char *cp;
34daa934dcSbill
35daa934dcSbill /* throw away null lines */
36daa934dcSbill if (sp->next->word[0] == '\n')
37daa934dcSbill return;
38f3328da7Sbostic cp = value(STRhistory);
39d60d469cSedward if (*cp) {
40f3328da7Sbostic register Char *p = cp;
41d60d469cSedward
42d60d469cSedward while (*p) {
43f3328da7Sbostic if (!Isdigit(*p)) {
44d60d469cSedward histlen = 0;
45d60d469cSedward break;
46d60d469cSedward }
47d60d469cSedward histlen = histlen * 10 + *p++ - '0';
48d60d469cSedward }
49d60d469cSedward }
5050cee248Schristos for (hp = &Histlist; (np = hp->Hnext) != NULL;)
51daa934dcSbill if (eventno - np->Href >= histlen || histlen == 0)
52daa934dcSbill hp->Hnext = np->Hnext, hfree(np);
53daa934dcSbill else
54daa934dcSbill hp = np;
55d60d469cSedward (void) enthist(++eventno, sp, 1);
56daa934dcSbill }
57daa934dcSbill
58daa934dcSbill struct Hist *
enthist(event,lp,docopy)59daa934dcSbill enthist(event, lp, docopy)
60daa934dcSbill int event;
61daa934dcSbill register struct wordent *lp;
62daa934dcSbill bool docopy;
63daa934dcSbill {
64daa934dcSbill register struct Hist *np;
65daa934dcSbill
66f3328da7Sbostic np = (struct Hist *) xmalloc((size_t) sizeof(*np));
67daa934dcSbill np->Hnum = np->Href = event;
68f3328da7Sbostic if (docopy) {
69daa934dcSbill copylex(&np->Hlex, lp);
70f3328da7Sbostic }
71daa934dcSbill else {
72daa934dcSbill np->Hlex.next = lp->next;
73daa934dcSbill lp->next->prev = &np->Hlex;
74daa934dcSbill np->Hlex.prev = lp->prev;
75daa934dcSbill lp->prev->next = &np->Hlex;
76daa934dcSbill }
77daa934dcSbill np->Hnext = Histlist.Hnext;
78daa934dcSbill Histlist.Hnext = np;
79daa934dcSbill return (np);
80daa934dcSbill }
81daa934dcSbill
82f3328da7Sbostic static void
hfree(hp)83daa934dcSbill hfree(hp)
84daa934dcSbill register struct Hist *hp;
85daa934dcSbill {
86daa934dcSbill
87daa934dcSbill freelex(&hp->Hlex);
88f3328da7Sbostic xfree((ptr_t) hp);
89daa934dcSbill }
90daa934dcSbill
91f3328da7Sbostic void
92cce51c35Schristos /*ARGSUSED*/
dohist(v,t)93cce51c35Schristos dohist(v, t)
94cce51c35Schristos Char **v;
95cce51c35Schristos struct command *t;
96daa934dcSbill {
97cce51c35Schristos int n, rflg = 0, hflg = 0;
98*5fad6ed4Schristos sigset_t sigset;
99f3328da7Sbostic
100f3328da7Sbostic if (getn(value(STRhistory)) == 0)
101daa934dcSbill return;
102*5fad6ed4Schristos if (setintr) {
103*5fad6ed4Schristos sigemptyset(&sigset);
104*5fad6ed4Schristos sigaddset(&sigset, SIGINT);
105*5fad6ed4Schristos sigprocmask(SIG_UNBLOCK, &sigset, NULL);
106*5fad6ed4Schristos }
107cce51c35Schristos while (*++v && **v == '-') {
108cce51c35Schristos Char *vp = *v;
109b750b233Smckusick
110cce51c35Schristos while (*++vp)
111cce51c35Schristos switch (*vp) {
112b750b233Smckusick case 'h':
11355318591Smckusic hflg++;
114b750b233Smckusick break;
115b750b233Smckusick case 'r':
116daa934dcSbill rflg++;
117b750b233Smckusick break;
118b750b233Smckusick case '-': /* ignore multiple '-'s */
119b750b233Smckusick break;
120b750b233Smckusick default:
121f3328da7Sbostic stderror(ERR_HISTUS);
122f3328da7Sbostic break;
123b750b233Smckusick }
124daa934dcSbill }
125cce51c35Schristos if (*v)
126cce51c35Schristos n = getn(*v);
12755318591Smckusic else {
128f3328da7Sbostic n = getn(value(STRhistory));
12955318591Smckusic }
130cce51c35Schristos dohist1(Histlist.Hnext, &n, rflg, hflg);
131daa934dcSbill }
132daa934dcSbill
133f3328da7Sbostic static void
dohist1(hp,np,rflg,hflg)134cce51c35Schristos dohist1(hp, np, rflg, hflg)
135daa934dcSbill struct Hist *hp;
136cce51c35Schristos int *np, rflg, hflg;
137daa934dcSbill {
138daa934dcSbill bool print = (*np) > 0;
139f3328da7Sbostic
140f3328da7Sbostic for (; hp != 0; hp = hp->Hnext) {
141daa934dcSbill (*np)--;
142daa934dcSbill hp->Href++;
143daa934dcSbill if (rflg == 0) {
144cce51c35Schristos dohist1(hp->Hnext, np, rflg, hflg);
145daa934dcSbill if (print)
146cce51c35Schristos phist(hp, hflg);
147daa934dcSbill return;
148daa934dcSbill }
149daa934dcSbill if (*np >= 0)
150cce51c35Schristos phist(hp, hflg);
151f3328da7Sbostic }
152daa934dcSbill }
153daa934dcSbill
154f3328da7Sbostic static void
phist(hp,hflg)155cce51c35Schristos phist(hp, hflg)
156daa934dcSbill register struct Hist *hp;
157cce51c35Schristos int hflg;
158daa934dcSbill {
159cce51c35Schristos if (hflg == 0)
160cce51c35Schristos (void) fprintf(cshout, "%6d\t", hp->Hnum);
161cce51c35Schristos prlex(cshout, &hp->Hlex);
162daa934dcSbill }
163