17c478bd9Sstevel@tonic-gate /*
2*6c02b4a4Smuffin * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
77c478bd9Sstevel@tonic-gate /* All Rights Reserved */
87c478bd9Sstevel@tonic-gate
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California.
117c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley Software License Agreement
127c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution.
137c478bd9Sstevel@tonic-gate */
147c478bd9Sstevel@tonic-gate
157c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
167c478bd9Sstevel@tonic-gate
177c478bd9Sstevel@tonic-gate #include "sh.h"
187c478bd9Sstevel@tonic-gate #include "sh.tconst.h"
197c478bd9Sstevel@tonic-gate
20*6c02b4a4Smuffin struct Hist *enthist(int, struct wordent *, bool);
21*6c02b4a4Smuffin void hfree(struct Hist *);
22*6c02b4a4Smuffin void dohist1(struct Hist *, int *, int, int);
23*6c02b4a4Smuffin void phist(struct Hist *, int);
24*6c02b4a4Smuffin
257c478bd9Sstevel@tonic-gate /*
267c478bd9Sstevel@tonic-gate * C shell
277c478bd9Sstevel@tonic-gate */
287c478bd9Sstevel@tonic-gate
29*6c02b4a4Smuffin void
savehist(struct wordent * sp)30*6c02b4a4Smuffin savehist(struct wordent *sp)
317c478bd9Sstevel@tonic-gate {
32*6c02b4a4Smuffin struct Hist *hp, *np;
33*6c02b4a4Smuffin int histlen = 0;
347c478bd9Sstevel@tonic-gate tchar *cp;
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate #ifdef TRACE
377c478bd9Sstevel@tonic-gate tprintf("TRACE- savehist()\n");
387c478bd9Sstevel@tonic-gate #endif
397c478bd9Sstevel@tonic-gate /* throw away null lines */
407c478bd9Sstevel@tonic-gate if (sp->next->word[0] == '\n')
417c478bd9Sstevel@tonic-gate return;
427c478bd9Sstevel@tonic-gate cp = value(S_history /*"history"*/);
437c478bd9Sstevel@tonic-gate if (*cp) {
44*6c02b4a4Smuffin tchar *p = cp;
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate while (*p) {
477c478bd9Sstevel@tonic-gate if (!digit(*p)) {
487c478bd9Sstevel@tonic-gate histlen = 0;
497c478bd9Sstevel@tonic-gate break;
507c478bd9Sstevel@tonic-gate }
517c478bd9Sstevel@tonic-gate histlen = histlen * 10 + *p++ - '0';
527c478bd9Sstevel@tonic-gate }
537c478bd9Sstevel@tonic-gate }
547c478bd9Sstevel@tonic-gate for (hp = &Histlist; np = hp->Hnext;)
557c478bd9Sstevel@tonic-gate if (eventno - np->Href >= histlen || histlen == 0)
567c478bd9Sstevel@tonic-gate hp->Hnext = np->Hnext, hfree(np);
577c478bd9Sstevel@tonic-gate else
587c478bd9Sstevel@tonic-gate hp = np;
597c478bd9Sstevel@tonic-gate (void) enthist(++eventno, sp, 1);
607c478bd9Sstevel@tonic-gate }
617c478bd9Sstevel@tonic-gate
627c478bd9Sstevel@tonic-gate struct Hist *
enthist(int event,struct wordent * lp,bool docopy)63*6c02b4a4Smuffin enthist(int event, struct wordent *lp, bool docopy)
647c478bd9Sstevel@tonic-gate {
65*6c02b4a4Smuffin struct Hist *np;
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate #ifdef TRACE
687c478bd9Sstevel@tonic-gate tprintf("TRACE- enthist()\n");
697c478bd9Sstevel@tonic-gate #endif
707c478bd9Sstevel@tonic-gate np = (struct Hist *) xalloc(sizeof *np);
717c478bd9Sstevel@tonic-gate np->Hnum = np->Href = event;
727c478bd9Sstevel@tonic-gate if (docopy)
737c478bd9Sstevel@tonic-gate copylex(&np->Hlex, lp);
747c478bd9Sstevel@tonic-gate else {
757c478bd9Sstevel@tonic-gate np->Hlex.next = lp->next;
767c478bd9Sstevel@tonic-gate lp->next->prev = &np->Hlex;
777c478bd9Sstevel@tonic-gate np->Hlex.prev = lp->prev;
787c478bd9Sstevel@tonic-gate lp->prev->next = &np->Hlex;
797c478bd9Sstevel@tonic-gate }
807c478bd9Sstevel@tonic-gate np->Hnext = Histlist.Hnext;
817c478bd9Sstevel@tonic-gate Histlist.Hnext = np;
827c478bd9Sstevel@tonic-gate return (np);
837c478bd9Sstevel@tonic-gate }
847c478bd9Sstevel@tonic-gate
85*6c02b4a4Smuffin void
hfree(struct Hist * hp)86*6c02b4a4Smuffin hfree(struct Hist *hp)
877c478bd9Sstevel@tonic-gate {
887c478bd9Sstevel@tonic-gate #ifdef TRACE
897c478bd9Sstevel@tonic-gate tprintf("TRACE- hfree()\n");
907c478bd9Sstevel@tonic-gate #endif
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate freelex(&hp->Hlex);
937c478bd9Sstevel@tonic-gate xfree( (tchar *)hp);
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate
96*6c02b4a4Smuffin void
dohist(tchar ** vp)97*6c02b4a4Smuffin dohist(tchar **vp)
987c478bd9Sstevel@tonic-gate {
997c478bd9Sstevel@tonic-gate int n, rflg = 0, hflg = 0;
1007c478bd9Sstevel@tonic-gate #ifdef TRACE
1017c478bd9Sstevel@tonic-gate tprintf("TRACE- dohist()\n");
1027c478bd9Sstevel@tonic-gate #endif
1037c478bd9Sstevel@tonic-gate if (getn(value(S_history /*"history"*/)) == 0)
1047c478bd9Sstevel@tonic-gate return;
1057c478bd9Sstevel@tonic-gate if (setintr)
1067c478bd9Sstevel@tonic-gate (void) sigsetmask(sigblock(0) & ~sigmask(SIGINT));
1077c478bd9Sstevel@tonic-gate while (*++vp && **vp == '-') {
1087c478bd9Sstevel@tonic-gate tchar *vp2 = *vp;
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate while (*++vp2)
1117c478bd9Sstevel@tonic-gate switch (*vp2) {
1127c478bd9Sstevel@tonic-gate case 'h':
1137c478bd9Sstevel@tonic-gate hflg++;
1147c478bd9Sstevel@tonic-gate break;
1157c478bd9Sstevel@tonic-gate case 'r':
1167c478bd9Sstevel@tonic-gate rflg++;
1177c478bd9Sstevel@tonic-gate break;
1187c478bd9Sstevel@tonic-gate case '-': /* ignore multiple '-'s */
1197c478bd9Sstevel@tonic-gate break;
1207c478bd9Sstevel@tonic-gate default:
1217c478bd9Sstevel@tonic-gate printf("Unknown flag: -%c\n", *vp2);
1227c478bd9Sstevel@tonic-gate error("Usage: history [-rh] [# number of events]");
1237c478bd9Sstevel@tonic-gate }
1247c478bd9Sstevel@tonic-gate }
1257c478bd9Sstevel@tonic-gate if (*vp)
1267c478bd9Sstevel@tonic-gate n = getn(*vp);
1277c478bd9Sstevel@tonic-gate else {
1287c478bd9Sstevel@tonic-gate n = getn(value(S_history /*"history"*/));
1297c478bd9Sstevel@tonic-gate }
1307c478bd9Sstevel@tonic-gate dohist1(Histlist.Hnext, &n, rflg, hflg);
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate
133*6c02b4a4Smuffin void
dohist1(struct Hist * hp,int * np,int rflg,int hflg)134*6c02b4a4Smuffin dohist1(struct Hist *hp, int *np, int rflg, int hflg)
1357c478bd9Sstevel@tonic-gate {
1367c478bd9Sstevel@tonic-gate bool print = (*np) > 0;
1377c478bd9Sstevel@tonic-gate #ifdef TRACE
1387c478bd9Sstevel@tonic-gate tprintf("TRACE- dohist1()\n");
1397c478bd9Sstevel@tonic-gate #endif
1407c478bd9Sstevel@tonic-gate top:
1417c478bd9Sstevel@tonic-gate if (hp == 0)
1427c478bd9Sstevel@tonic-gate return;
1437c478bd9Sstevel@tonic-gate (*np)--;
1447c478bd9Sstevel@tonic-gate hp->Href++;
1457c478bd9Sstevel@tonic-gate if (rflg == 0) {
1467c478bd9Sstevel@tonic-gate dohist1(hp->Hnext, np, rflg, hflg);
1477c478bd9Sstevel@tonic-gate if (print)
1487c478bd9Sstevel@tonic-gate phist(hp, hflg);
1497c478bd9Sstevel@tonic-gate return;
1507c478bd9Sstevel@tonic-gate }
1517c478bd9Sstevel@tonic-gate if (*np >= 0)
1527c478bd9Sstevel@tonic-gate phist(hp, hflg);
1537c478bd9Sstevel@tonic-gate hp = hp->Hnext;
1547c478bd9Sstevel@tonic-gate goto top;
1557c478bd9Sstevel@tonic-gate }
1567c478bd9Sstevel@tonic-gate
157*6c02b4a4Smuffin void
phist(struct Hist * hp,int hflg)158*6c02b4a4Smuffin phist(struct Hist *hp, int hflg)
1597c478bd9Sstevel@tonic-gate {
1607c478bd9Sstevel@tonic-gate #ifdef TRACE
1617c478bd9Sstevel@tonic-gate tprintf("TRACE- phist()\n");
1627c478bd9Sstevel@tonic-gate #endif
1637c478bd9Sstevel@tonic-gate
1647c478bd9Sstevel@tonic-gate if (hflg == 0)
1657c478bd9Sstevel@tonic-gate printf("%6d\t", hp->Hnum);
1667c478bd9Sstevel@tonic-gate prlex(&hp->Hlex);
1677c478bd9Sstevel@tonic-gate }
168