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