xref: /minix/bin/csh/hist.c (revision ebfedea0)
1 /* $NetBSD: hist.c,v 1.20 2013/07/16 17:47:43 christos Exp $ */
2 
3 /*-
4  * Copyright (c) 1980, 1991, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)hist.c	8.1 (Berkeley) 5/31/93";
36 #else
37 __RCSID("$NetBSD: hist.c,v 1.20 2013/07/16 17:47:43 christos Exp $");
38 #endif
39 #endif /* not lint */
40 
41 #include <sys/types.h>
42 
43 #include <stdarg.h>
44 #include <stdlib.h>
45 
46 #include "csh.h"
47 #include "extern.h"
48 
49 static void hfree(struct Hist *);
50 static void dohist1(struct Hist *, int *, int, int);
51 static void phist(struct Hist *, int);
52 
53 void
54 savehist(struct wordent *sp)
55 {
56     struct Hist *hp, *np;
57     Char *cp;
58     int histlen;
59 
60     histlen = 0;
61 
62     /* throw away null lines */
63     if (sp->next->word[0] == '\n')
64 	return;
65     cp = value(STRhistory);
66     if (*cp) {
67 	Char *p = cp;
68 
69 	while (*p) {
70 	    if (!Isdigit(*p)) {
71 		histlen = 0;
72 		break;
73 	    }
74 	    histlen = histlen * 10 + *p++ - '0';
75 	}
76     }
77     for (hp = &Histlist; (np = hp->Hnext) != NULL;)
78 	if (eventno - np->Href >= histlen || histlen == 0)
79 	    hp->Hnext = np->Hnext, hfree(np);
80 	else
81 	    hp = np;
82     (void) enthist(++eventno, sp, 1);
83 }
84 
85 #ifdef EDIT
86 void
87 loadhist(struct Hist *hp) {
88     char *h = NULL;
89 
90     if (hi == NULL || hp == NULL)
91 	return;
92     loadhist(hp->Hnext);
93     if (sprlex(&h, &hp->Hlex) != -1) {
94 	HistEvent ev;
95 	history(hi, &ev, H_ENTER, h);
96     }
97 }
98 #endif
99 
100 struct Hist *
101 enthist(int event, struct wordent *lp, int docopy)
102 {
103     struct Hist *np;
104 
105 #ifdef EDIT
106     if (hi) {
107 	char *h = NULL;
108 	if (sprlex(&h, lp) != -1) {
109 	    HistEvent ev;
110 	    history(hi, &ev, H_ENTER, h);
111 	}
112     }
113 #endif
114     np = xmalloc(sizeof(*np));
115     np->Hnum = np->Href = event;
116     if (docopy) {
117 	copylex(&np->Hlex, lp);
118     }
119     else {
120 	np->Hlex.next = lp->next;
121 	lp->next->prev = &np->Hlex;
122 	np->Hlex.prev = lp->prev;
123 	lp->prev->next = &np->Hlex;
124     }
125     np->Hnext = Histlist.Hnext;
126     Histlist.Hnext = np;
127     return (np);
128 }
129 
130 static void
131 hfree(struct Hist *hp)
132 {
133     freelex(&hp->Hlex);
134     xfree((ptr_t) hp);
135 }
136 
137 void
138 /*ARGSUSED*/
139 dohist(Char **v, struct command *t)
140 {
141     sigset_t nsigset;
142     int hflg, n, rflg;
143 
144     hflg = 0;
145     rflg = 0;
146 
147     if (getn(value(STRhistory)) == 0)
148 	return;
149     if (setintr) {
150 	sigemptyset(&nsigset);
151 	(void)sigaddset(&nsigset, SIGINT);
152 	(void)sigprocmask(SIG_UNBLOCK, &nsigset, NULL);
153     }
154     while (*++v && **v == '-') {
155 	Char *vp = *v;
156 
157 	while (*++vp)
158 	    switch (*vp) {
159 	    case 'h':
160 		hflg++;
161 		break;
162 	    case 'r':
163 		rflg++;
164 		break;
165 	    case '-':		/* ignore multiple '-'s */
166 		break;
167 	    default:
168 		stderror(ERR_HISTUS);
169 		/* NOTREACHED */
170 	    }
171     }
172     if (*v)
173 	n = getn(*v);
174     else {
175 	n = getn(value(STRhistory));
176     }
177     dohist1(Histlist.Hnext, &n, rflg, hflg);
178 }
179 
180 static void
181 dohist1(struct Hist *hp, int *np, int rflg, int hflg)
182 {
183     int print;
184 
185     print = (*np) > 0;
186 
187     for (; hp != 0; hp = hp->Hnext) {
188 	(*np)--;
189 	hp->Href++;
190 	if (rflg == 0) {
191 	    dohist1(hp->Hnext, np, rflg, hflg);
192 	    if (print)
193 		phist(hp, hflg);
194 	    return;
195 	}
196 	if (*np >= 0)
197 	    phist(hp, hflg);
198     }
199 }
200 
201 static void
202 phist(struct Hist *hp, int hflg)
203 {
204     if (hflg == 0)
205 	(void)fprintf(cshout, "%6d\t", hp->Hnum);
206     prlex(cshout, &hp->Hlex);
207 }
208