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