xref: /original-bsd/bin/csh/hist.c (revision 138cce1a)
1 /*-
2  * Copyright (c) 1980, 1991 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)hist.c	5.9 (Berkeley) 06/08/91";
10 #endif /* not lint */
11 
12 #include <sys/types.h>
13 #include <stdlib.h>
14 #if __STDC__
15 # include <stdarg.h>
16 #else
17 # include <varargs.h>
18 #endif
19 
20 #include "csh.h"
21 #include "extern.h"
22 
23 static void	hfree __P((struct Hist *));
24 static void	dohist1 __P((struct Hist *, int *, int, int, int));
25 static void	phist __P((struct Hist *, int, int));
26 
27 void
28 savehist(sp)
29     struct wordent *sp;
30 {
31     register struct Hist *hp, *np;
32     register int histlen = 0;
33     Char   *cp;
34 
35     /* throw away null lines */
36     if (sp->next->word[0] == '\n')
37 	return;
38     cp = value(STRhistory);
39     if (*cp) {
40 	register Char *p = cp;
41 
42 	while (*p) {
43 	    if (!Isdigit(*p)) {
44 		histlen = 0;
45 		break;
46 	    }
47 	    histlen = histlen * 10 + *p++ - '0';
48 	}
49     }
50     for (hp = &Histlist; np = hp->Hnext;)
51 	if (eventno - np->Href >= histlen || histlen == 0)
52 	    hp->Hnext = np->Hnext, hfree(np);
53 	else
54 	    hp = np;
55     (void) enthist(++eventno, sp, 1);
56 }
57 
58 struct Hist *
59 enthist(event, lp, docopy)
60     int     event;
61     register struct wordent *lp;
62     bool    docopy;
63 {
64     register struct Hist *np;
65 
66     np = (struct Hist *) xmalloc((size_t) sizeof(*np));
67     (void) time(&(np->Htime));
68     np->Hnum = np->Href = event;
69     if (docopy) {
70 	copylex(&np->Hlex, lp);
71     }
72     else {
73 	np->Hlex.next = lp->next;
74 	lp->next->prev = &np->Hlex;
75 	np->Hlex.prev = lp->prev;
76 	lp->prev->next = &np->Hlex;
77     }
78     np->Hnext = Histlist.Hnext;
79     Histlist.Hnext = np;
80     return (np);
81 }
82 
83 static void
84 hfree(hp)
85     register struct Hist *hp;
86 {
87 
88     freelex(&hp->Hlex);
89     xfree((ptr_t) hp);
90 }
91 
92 void
93 dohist(vp)
94     Char  **vp;
95 {
96     int     n, rflg = 0, hflg = 0, tflg = 0;
97 
98     if (getn(value(STRhistory)) == 0)
99 	return;
100     if (setintr)
101 	(void) sigsetmask(sigblock((sigset_t) 0) & ~sigmask(SIGINT));
102     while (*++vp && **vp == '-') {
103 	Char   *vp2 = *vp;
104 
105 	while (*++vp2)
106 	    switch (*vp2) {
107 	    case 'h':
108 		hflg++;
109 		break;
110 	    case 'r':
111 		rflg++;
112 		break;
113 	    case 't':
114 		tflg++;
115 		break;
116 	    case '-':		/* ignore multiple '-'s */
117 		break;
118 	    default:
119 		stderror(ERR_HISTUS);
120 		break;
121 	    }
122     }
123     if (*vp)
124 	n = getn(*vp);
125     else {
126 	n = getn(value(STRhistory));
127     }
128     dohist1(Histlist.Hnext, &n, rflg, hflg, tflg);
129 }
130 
131 static void
132 dohist1(hp, np, rflg, hflg, tflg)
133     struct Hist *hp;
134     int    *np, rflg, hflg, tflg;
135 {
136     bool    print = (*np) > 0;
137 
138     for (; hp != 0; hp = hp->Hnext) {
139 	(*np)--;
140 	hp->Href++;
141 	if (rflg == 0) {
142 	    dohist1(hp->Hnext, np, rflg, hflg, tflg);
143 	    if (print)
144 		phist(hp, hflg, tflg);
145 	    return;
146 	}
147 	if (*np >= 0)
148 	    phist(hp, hflg, tflg);
149     }
150 }
151 
152 static void
153 phist(hp, hflg, tflg)
154     register struct Hist *hp;
155     int     hflg, tflg;
156 {
157     struct tm *t;
158     char    ampm = 'a';
159 
160     if (hflg == 0) {
161 	xprintf("%6d\t", hp->Hnum);
162 	if (tflg == 0) {
163 	    t = localtime(&hp->Htime);
164 	    if (adrof(STRampm)) {	/* addition by Hans J. Albertsson */
165 		if (t->tm_hour >= 12) {
166 		    if (t->tm_hour > 12)
167 			t->tm_hour -= 12;
168 		    ampm = 'p';
169 		}
170 		else if (t->tm_hour == 0)
171 		    t->tm_hour = 12;
172 		xprintf("%2d:%02d%cm\t", t->tm_hour, t->tm_min, ampm);
173 	    }
174 	    else {
175 		xprintf("%2d:%02d\t", t->tm_hour, t->tm_min);
176 	    }
177 	}
178     }
179     prlex(&hp->Hlex);
180 }
181