xref: /onnv-gate/usr/src/cmd/csh/sh.hist.c (revision 356:44e9075e1c86)
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