10Sstevel@tonic-gate /*
2*356Smuffin * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
30Sstevel@tonic-gate * Use is subject to license terms.
40Sstevel@tonic-gate */
50Sstevel@tonic-gate
60Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
70Sstevel@tonic-gate /* All Rights Reserved */
80Sstevel@tonic-gate
90Sstevel@tonic-gate /*
100Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California.
110Sstevel@tonic-gate * All rights reserved. The Berkeley Software License Agreement
120Sstevel@tonic-gate * specifies the terms and conditions for redistribution.
130Sstevel@tonic-gate */
140Sstevel@tonic-gate
150Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
160Sstevel@tonic-gate
170Sstevel@tonic-gate #include "sh.h"
180Sstevel@tonic-gate #include "sh.tconst.h"
190Sstevel@tonic-gate
20*356Smuffin struct Hist *enthist(int, struct wordent *, bool);
21*356Smuffin void hfree(struct Hist *);
22*356Smuffin void dohist1(struct Hist *, int *, int, int);
23*356Smuffin void phist(struct Hist *, int);
24*356Smuffin
250Sstevel@tonic-gate /*
260Sstevel@tonic-gate * C shell
270Sstevel@tonic-gate */
280Sstevel@tonic-gate
29*356Smuffin void
savehist(struct wordent * sp)30*356Smuffin savehist(struct wordent *sp)
310Sstevel@tonic-gate {
32*356Smuffin struct Hist *hp, *np;
33*356Smuffin int histlen = 0;
340Sstevel@tonic-gate tchar *cp;
350Sstevel@tonic-gate
360Sstevel@tonic-gate #ifdef TRACE
370Sstevel@tonic-gate tprintf("TRACE- savehist()\n");
380Sstevel@tonic-gate #endif
390Sstevel@tonic-gate /* throw away null lines */
400Sstevel@tonic-gate if (sp->next->word[0] == '\n')
410Sstevel@tonic-gate return;
420Sstevel@tonic-gate cp = value(S_history /*"history"*/);
430Sstevel@tonic-gate if (*cp) {
44*356Smuffin tchar *p = cp;
450Sstevel@tonic-gate
460Sstevel@tonic-gate while (*p) {
470Sstevel@tonic-gate if (!digit(*p)) {
480Sstevel@tonic-gate histlen = 0;
490Sstevel@tonic-gate break;
500Sstevel@tonic-gate }
510Sstevel@tonic-gate histlen = histlen * 10 + *p++ - '0';
520Sstevel@tonic-gate }
530Sstevel@tonic-gate }
540Sstevel@tonic-gate for (hp = &Histlist; np = hp->Hnext;)
550Sstevel@tonic-gate if (eventno - np->Href >= histlen || histlen == 0)
560Sstevel@tonic-gate hp->Hnext = np->Hnext, hfree(np);
570Sstevel@tonic-gate else
580Sstevel@tonic-gate hp = np;
590Sstevel@tonic-gate (void) enthist(++eventno, sp, 1);
600Sstevel@tonic-gate }
610Sstevel@tonic-gate
620Sstevel@tonic-gate struct Hist *
enthist(int event,struct wordent * lp,bool docopy)63*356Smuffin enthist(int event, struct wordent *lp, bool docopy)
640Sstevel@tonic-gate {
65*356Smuffin struct Hist *np;
660Sstevel@tonic-gate
670Sstevel@tonic-gate #ifdef TRACE
680Sstevel@tonic-gate tprintf("TRACE- enthist()\n");
690Sstevel@tonic-gate #endif
700Sstevel@tonic-gate np = (struct Hist *) xalloc(sizeof *np);
710Sstevel@tonic-gate np->Hnum = np->Href = event;
720Sstevel@tonic-gate if (docopy)
730Sstevel@tonic-gate copylex(&np->Hlex, lp);
740Sstevel@tonic-gate else {
750Sstevel@tonic-gate np->Hlex.next = lp->next;
760Sstevel@tonic-gate lp->next->prev = &np->Hlex;
770Sstevel@tonic-gate np->Hlex.prev = lp->prev;
780Sstevel@tonic-gate lp->prev->next = &np->Hlex;
790Sstevel@tonic-gate }
800Sstevel@tonic-gate np->Hnext = Histlist.Hnext;
810Sstevel@tonic-gate Histlist.Hnext = np;
820Sstevel@tonic-gate return (np);
830Sstevel@tonic-gate }
840Sstevel@tonic-gate
85*356Smuffin void
hfree(struct Hist * hp)86*356Smuffin hfree(struct Hist *hp)
870Sstevel@tonic-gate {
880Sstevel@tonic-gate #ifdef TRACE
890Sstevel@tonic-gate tprintf("TRACE- hfree()\n");
900Sstevel@tonic-gate #endif
910Sstevel@tonic-gate
920Sstevel@tonic-gate freelex(&hp->Hlex);
930Sstevel@tonic-gate xfree( (tchar *)hp);
940Sstevel@tonic-gate }
950Sstevel@tonic-gate
96*356Smuffin void
dohist(tchar ** vp)97*356Smuffin dohist(tchar **vp)
980Sstevel@tonic-gate {
990Sstevel@tonic-gate int n, rflg = 0, hflg = 0;
1000Sstevel@tonic-gate #ifdef TRACE
1010Sstevel@tonic-gate tprintf("TRACE- dohist()\n");
1020Sstevel@tonic-gate #endif
1030Sstevel@tonic-gate if (getn(value(S_history /*"history"*/)) == 0)
1040Sstevel@tonic-gate return;
1050Sstevel@tonic-gate if (setintr)
1060Sstevel@tonic-gate (void) sigsetmask(sigblock(0) & ~sigmask(SIGINT));
1070Sstevel@tonic-gate while (*++vp && **vp == '-') {
1080Sstevel@tonic-gate tchar *vp2 = *vp;
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate while (*++vp2)
1110Sstevel@tonic-gate switch (*vp2) {
1120Sstevel@tonic-gate case 'h':
1130Sstevel@tonic-gate hflg++;
1140Sstevel@tonic-gate break;
1150Sstevel@tonic-gate case 'r':
1160Sstevel@tonic-gate rflg++;
1170Sstevel@tonic-gate break;
1180Sstevel@tonic-gate case '-': /* ignore multiple '-'s */
1190Sstevel@tonic-gate break;
1200Sstevel@tonic-gate default:
1210Sstevel@tonic-gate printf("Unknown flag: -%c\n", *vp2);
1220Sstevel@tonic-gate error("Usage: history [-rh] [# number of events]");
1230Sstevel@tonic-gate }
1240Sstevel@tonic-gate }
1250Sstevel@tonic-gate if (*vp)
1260Sstevel@tonic-gate n = getn(*vp);
1270Sstevel@tonic-gate else {
1280Sstevel@tonic-gate n = getn(value(S_history /*"history"*/));
1290Sstevel@tonic-gate }
1300Sstevel@tonic-gate dohist1(Histlist.Hnext, &n, rflg, hflg);
1310Sstevel@tonic-gate }
1320Sstevel@tonic-gate
133*356Smuffin void
dohist1(struct Hist * hp,int * np,int rflg,int hflg)134*356Smuffin dohist1(struct Hist *hp, int *np, int rflg, int hflg)
1350Sstevel@tonic-gate {
1360Sstevel@tonic-gate bool print = (*np) > 0;
1370Sstevel@tonic-gate #ifdef TRACE
1380Sstevel@tonic-gate tprintf("TRACE- dohist1()\n");
1390Sstevel@tonic-gate #endif
1400Sstevel@tonic-gate top:
1410Sstevel@tonic-gate if (hp == 0)
1420Sstevel@tonic-gate return;
1430Sstevel@tonic-gate (*np)--;
1440Sstevel@tonic-gate hp->Href++;
1450Sstevel@tonic-gate if (rflg == 0) {
1460Sstevel@tonic-gate dohist1(hp->Hnext, np, rflg, hflg);
1470Sstevel@tonic-gate if (print)
1480Sstevel@tonic-gate phist(hp, hflg);
1490Sstevel@tonic-gate return;
1500Sstevel@tonic-gate }
1510Sstevel@tonic-gate if (*np >= 0)
1520Sstevel@tonic-gate phist(hp, hflg);
1530Sstevel@tonic-gate hp = hp->Hnext;
1540Sstevel@tonic-gate goto top;
1550Sstevel@tonic-gate }
1560Sstevel@tonic-gate
157*356Smuffin void
phist(struct Hist * hp,int hflg)158*356Smuffin phist(struct Hist *hp, int hflg)
1590Sstevel@tonic-gate {
1600Sstevel@tonic-gate #ifdef TRACE
1610Sstevel@tonic-gate tprintf("TRACE- phist()\n");
1620Sstevel@tonic-gate #endif
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate if (hflg == 0)
1650Sstevel@tonic-gate printf("%6d\t", hp->Hnum);
1660Sstevel@tonic-gate prlex(&hp->Hlex);
1670Sstevel@tonic-gate }
168