1 /*- 2 * Copyright (c) 1980, 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 static char sccsid[] = "@(#)hist.c 5.9 (Berkeley) 6/8/91"; 36 static char rcsid[] = "$Header: /cvsroot/src/bin/csh/hist.c,v 1.3 1993/03/23 00:24:51 cgd Exp $"; 37 #endif /* not lint */ 38 39 #include <sys/types.h> 40 #include <stdlib.h> 41 #if __STDC__ 42 # include <stdarg.h> 43 #else 44 # include <varargs.h> 45 #endif 46 47 #include "csh.h" 48 #include "extern.h" 49 50 static void hfree __P((struct Hist *)); 51 static void dohist1 __P((struct Hist *, int *, int, int, int)); 52 static void phist __P((struct Hist *, int, int)); 53 54 void 55 savehist(sp) 56 struct wordent *sp; 57 { 58 register struct Hist *hp, *np; 59 register int histlen = 0; 60 Char *cp; 61 62 /* throw away null lines */ 63 if (sp->next->word[0] == '\n') 64 return; 65 cp = value(STRhistory); 66 if (*cp) { 67 register 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;) 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 struct Hist * 86 enthist(event, lp, docopy) 87 int event; 88 register struct wordent *lp; 89 bool docopy; 90 { 91 register struct Hist *np; 92 93 np = (struct Hist *) xmalloc((size_t) sizeof(*np)); 94 (void) time(&(np->Htime)); 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(hp) 112 register struct Hist *hp; 113 { 114 115 freelex(&hp->Hlex); 116 xfree((ptr_t) hp); 117 } 118 119 void 120 dohist(vp) 121 Char **vp; 122 { 123 int n, rflg = 0, hflg = 0, tflg = 0; 124 125 if (getn(value(STRhistory)) == 0) 126 return; 127 if (setintr) 128 (void) sigsetmask(sigblock((sigset_t) 0) & ~sigmask(SIGINT)); 129 while (*++vp && **vp == '-') { 130 Char *vp2 = *vp; 131 132 while (*++vp2) 133 switch (*vp2) { 134 case 'h': 135 hflg++; 136 break; 137 case 'r': 138 rflg++; 139 break; 140 case 't': 141 tflg++; 142 break; 143 case '-': /* ignore multiple '-'s */ 144 break; 145 default: 146 stderror(ERR_HISTUS); 147 break; 148 } 149 } 150 if (*vp) 151 n = getn(*vp); 152 else { 153 n = getn(value(STRhistory)); 154 } 155 dohist1(Histlist.Hnext, &n, rflg, hflg, tflg); 156 } 157 158 static void 159 dohist1(hp, np, rflg, hflg, tflg) 160 struct Hist *hp; 161 int *np, rflg, hflg, tflg; 162 { 163 bool print = (*np) > 0; 164 165 for (; hp != 0; hp = hp->Hnext) { 166 (*np)--; 167 hp->Href++; 168 if (rflg == 0) { 169 dohist1(hp->Hnext, np, rflg, hflg, tflg); 170 if (print) 171 phist(hp, hflg, tflg); 172 return; 173 } 174 if (*np >= 0) 175 phist(hp, hflg, tflg); 176 } 177 } 178 179 static void 180 phist(hp, hflg, tflg) 181 register struct Hist *hp; 182 int hflg, tflg; 183 { 184 struct tm *t; 185 char ampm = 'a'; 186 187 if (hflg == 0) { 188 xprintf("%6d\t", hp->Hnum); 189 if (tflg == 0) { 190 t = localtime(&hp->Htime); 191 if (adrof(STRampm)) { /* addition by Hans J. Albertsson */ 192 if (t->tm_hour >= 12) { 193 if (t->tm_hour > 12) 194 t->tm_hour -= 12; 195 ampm = 'p'; 196 } 197 else if (t->tm_hour == 0) 198 t->tm_hour = 12; 199 xprintf("%2d:%02d%cm\t", t->tm_hour, t->tm_min, ampm); 200 } 201 else { 202 xprintf("%2d:%02d\t", t->tm_hour, t->tm_min); 203 } 204 } 205 } 206 prlex(&hp->Hlex); 207 } 208