Home | History | Annotate | Line # | Download | only in csh
hist.c revision 1.12
      1 /* $NetBSD: hist.c,v 1.12 2001/09/14 14:04:00 wiz 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.12 2001/09/14 14:04:00 wiz Exp $");
     42 #endif
     43 #endif /* not lint */
     44 
     45 #include <sys/types.h>
     46 
     47 #include <stdlib.h>
     48 
     49 #if __STDC__
     50 # include <stdarg.h>
     51 #else
     52 # include <varargs.h>
     53 #endif
     54 
     55 #include "csh.h"
     56 #include "extern.h"
     57 
     58 static void hfree(struct Hist *);
     59 static void dohist1(struct Hist *, int *, int, int);
     60 static void phist(struct Hist *, int);
     61 
     62 void
     63 savehist(struct wordent *sp)
     64 {
     65     struct Hist *hp, *np;
     66     Char *cp;
     67     int histlen;
     68 
     69     histlen = 0;
     70 
     71     /* throw away null lines */
     72     if (sp->next->word[0] == '\n')
     73 	return;
     74     cp = value(STRhistory);
     75     if (*cp) {
     76 	Char *p = cp;
     77 
     78 	while (*p) {
     79 	    if (!Isdigit(*p)) {
     80 		histlen = 0;
     81 		break;
     82 	    }
     83 	    histlen = histlen * 10 + *p++ - '0';
     84 	}
     85     }
     86     for (hp = &Histlist; (np = hp->Hnext) != NULL;)
     87 	if (eventno - np->Href >= histlen || histlen == 0)
     88 	    hp->Hnext = np->Hnext, hfree(np);
     89 	else
     90 	    hp = np;
     91     (void) enthist(++eventno, sp, 1);
     92 }
     93 
     94 struct Hist *
     95 enthist(int event, struct wordent *lp, bool docopy)
     96 {
     97     struct Hist *np;
     98 
     99     np = (struct Hist *)xmalloc((size_t)sizeof(*np));
    100     np->Hnum = np->Href = event;
    101     if (docopy) {
    102 	copylex(&np->Hlex, lp);
    103     }
    104     else {
    105 	np->Hlex.next = lp->next;
    106 	lp->next->prev = &np->Hlex;
    107 	np->Hlex.prev = lp->prev;
    108 	lp->prev->next = &np->Hlex;
    109     }
    110     np->Hnext = Histlist.Hnext;
    111     Histlist.Hnext = np;
    112     return (np);
    113 }
    114 
    115 static void
    116 hfree(struct Hist *hp)
    117 {
    118     freelex(&hp->Hlex);
    119     xfree((ptr_t) hp);
    120 }
    121 
    122 void
    123 /*ARGSUSED*/
    124 dohist(Char **v, struct command *t)
    125 {
    126     sigset_t sigset;
    127     int hflg, n, rflg;
    128 
    129     hflg = 0;
    130     rflg = 0;
    131 
    132     if (getn(value(STRhistory)) == 0)
    133 	return;
    134     if (setintr) {
    135 	sigemptyset(&sigset);
    136 	(void)sigaddset(&sigset, SIGINT);
    137 	(void)sigprocmask(SIG_UNBLOCK, &sigset, NULL);
    138     }
    139     while (*++v && **v == '-') {
    140 	Char *vp = *v;
    141 
    142 	while (*++vp)
    143 	    switch (*vp) {
    144 	    case 'h':
    145 		hflg++;
    146 		break;
    147 	    case 'r':
    148 		rflg++;
    149 		break;
    150 	    case '-':		/* ignore multiple '-'s */
    151 		break;
    152 	    default:
    153 		stderror(ERR_HISTUS);
    154 		/* NOTREACHED */
    155 	    }
    156     }
    157     if (*v)
    158 	n = getn(*v);
    159     else {
    160 	n = getn(value(STRhistory));
    161     }
    162     dohist1(Histlist.Hnext, &n, rflg, hflg);
    163 }
    164 
    165 static void
    166 dohist1(struct Hist *hp, int *np, int rflg, int hflg)
    167 {
    168     bool print;
    169 
    170     print = (*np) > 0;
    171 
    172     for (; hp != 0; hp = hp->Hnext) {
    173 	(*np)--;
    174 	hp->Href++;
    175 	if (rflg == 0) {
    176 	    dohist1(hp->Hnext, np, rflg, hflg);
    177 	    if (print)
    178 		phist(hp, hflg);
    179 	    return;
    180 	}
    181 	if (*np >= 0)
    182 	    phist(hp, hflg);
    183     }
    184 }
    185 
    186 static void
    187 phist(struct Hist *hp, int hflg)
    188 {
    189     if (hflg == 0)
    190 	(void)fprintf(cshout, "%6d\t", hp->Hnum);
    191     prlex(cshout, &hp->Hlex);
    192 }
    193