xref: /original-bsd/bin/csh/hist.c (revision 47436896)
1 /*-
2  * Copyright (c) 1980, 1991 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)hist.c	5.10 (Berkeley) 07/19/91";
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;)
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 
99     if (getn(value(STRhistory)) == 0)
100 	return;
101     if (setintr)
102 	(void) sigsetmask(sigblock((sigset_t) 0) & ~sigmask(SIGINT));
103     while (*++v && **v == '-') {
104 	Char   *vp = *v;
105 
106 	while (*++vp)
107 	    switch (*vp) {
108 	    case 'h':
109 		hflg++;
110 		break;
111 	    case 'r':
112 		rflg++;
113 		break;
114 	    case '-':		/* ignore multiple '-'s */
115 		break;
116 	    default:
117 		stderror(ERR_HISTUS);
118 		break;
119 	    }
120     }
121     if (*v)
122 	n = getn(*v);
123     else {
124 	n = getn(value(STRhistory));
125     }
126     dohist1(Histlist.Hnext, &n, rflg, hflg);
127 }
128 
129 static void
130 dohist1(hp, np, rflg, hflg)
131     struct Hist *hp;
132     int    *np, rflg, hflg;
133 {
134     bool    print = (*np) > 0;
135 
136     for (; hp != 0; hp = hp->Hnext) {
137 	(*np)--;
138 	hp->Href++;
139 	if (rflg == 0) {
140 	    dohist1(hp->Hnext, np, rflg, hflg);
141 	    if (print)
142 		phist(hp, hflg);
143 	    return;
144 	}
145 	if (*np >= 0)
146 	    phist(hp, hflg);
147     }
148 }
149 
150 static void
151 phist(hp, hflg)
152     register struct Hist *hp;
153     int     hflg;
154 {
155     if (hflg == 0)
156 	(void) fprintf(cshout, "%6d\t", hp->Hnum);
157     prlex(cshout, &hp->Hlex);
158 }
159