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