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