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 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 * 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 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 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 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 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