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