source: trunk/third/tcsh/sh.hist.c @ 9006

Revision 9006, 7.7 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r9005, which included commits to RCS files with non-trunk default branches.
Line 
1/* $Header: /afs/dev.mit.edu/source/repository/third/tcsh/sh.hist.c,v 1.1.1.1 1996-10-02 06:09:21 ghudson Exp $ */
2/*
3 * sh.hist.c: Shell history expansions and substitutions
4 */
5/*-
6 * Copyright (c) 1980, 1991 The Regents of the University of California.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 *    must display the following acknowledgement:
19 *      This product includes software developed by the University of
20 *      California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 *    may be used to endorse or promote products derived from this software
23 *    without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37#include "sh.h"
38
39RCSID("$Id: sh.hist.c,v 1.1.1.1 1996-10-02 06:09:21 ghudson Exp $")
40
41#include "tc.h"
42
43extern bool histvalid;
44extern Char histline[];
45Char HistLit = 0;
46
47static  void    hfree   __P((struct Hist *));
48static  void    dohist1 __P((struct Hist *, int *, int));
49static  void    phist   __P((struct Hist *, int));
50
51#define HIST_ONLY       0x01
52#define HIST_SAVE       0x02
53#define HIST_LOAD       0x04
54#define HIST_REV        0x08
55#define HIST_CLEAR      0x10
56
57/*
58 * C shell
59 */
60
61void
62savehist(sp)
63    struct wordent *sp;
64{
65    register struct Hist *hp, *np;
66    register int histlen = 0;
67    Char   *cp;
68
69    /* throw away null lines */
70    if (sp->next->word[0] == '\n')
71        return;
72    cp = value(STRhistory);
73    if (*cp) {
74        register Char *p = cp;
75
76        while (*p) {
77            if (!Isdigit(*p)) {
78                histlen = 0;
79                break;
80            }
81            histlen = histlen * 10 + *p++ - '0';
82        }
83    }
84    for (hp = &Histlist; (np = hp->Hnext) != NULL;)
85        if (eventno - np->Href >= histlen || histlen == 0)
86            hp->Hnext = np->Hnext, hfree(np);
87        else
88            hp = np;
89    (void) enthist(++eventno, sp, 1);
90}
91
92struct Hist *
93enthist(event, lp, docopy)
94    int     event;
95    register struct wordent *lp;
96    bool    docopy;
97{
98    extern time_t Htime;
99    register struct Hist *np = (struct Hist *) xmalloc((size_t) sizeof(*np));
100
101    /* Pick up timestamp set by lex() in Htime if reading saved history */
102    if (Htime != (time_t) 0) {
103        np->Htime = Htime;
104        Htime = 0;
105    }
106    else
107        (void) time(&(np->Htime));
108
109    np->Hnum = np->Href = event;
110    if (docopy) {
111        copylex(&np->Hlex, lp);
112        if (histvalid)
113            np->histline = Strsave(histline);
114        else
115            np->histline = NULL;
116    }
117    else {
118        np->Hlex.next = lp->next;
119        lp->next->prev = &np->Hlex;
120        np->Hlex.prev = lp->prev;
121        lp->prev->next = &np->Hlex;
122        np->histline = NULL;
123    }
124    np->Hnext = Histlist.Hnext;
125    Histlist.Hnext = np;
126    return (np);
127}
128
129static void
130hfree(hp)
131    register struct Hist *hp;
132{
133
134    freelex(&hp->Hlex);
135    if (hp->histline)
136        xfree((ptr_t) hp->histline);
137    xfree((ptr_t) hp);
138}
139
140
141/*ARGSUSED*/
142void
143dohist(vp, c)
144    Char  **vp;
145    struct command *c;
146{
147    int     n, hflg = 0;
148
149    if (getn(value(STRhistory)) == 0)
150        return;
151    if (setintr)
152#ifdef BSDSIGS
153        (void) sigsetmask(sigblock((sigmask_t) 0) & ~sigmask(SIGINT));
154#else
155        (void) sigrelse(SIGINT);
156#endif
157    while (*++vp && **vp == '-') {
158        Char   *vp2 = *vp;
159
160        while (*++vp2)
161            switch (*vp2) {
162            case 'c':
163                hflg |= HIST_CLEAR;
164                break;
165            case 'h':
166                hflg |= HIST_ONLY;
167                break;
168            case 'r':
169                hflg |= HIST_REV;
170                break;
171            case 'S':
172                hflg |= HIST_SAVE;
173                break;
174            case 'L':
175                hflg |= HIST_LOAD;
176                break;
177            default:
178                stderror(ERR_HISTUS, "chrSL");
179                break;
180            }
181    }
182
183    if (hflg & HIST_CLEAR) {
184        struct Hist *np, *hp;
185        for (hp = &Histlist; (np = hp->Hnext) != NULL;)
186            hp->Hnext = np->Hnext, hfree(np);
187    }
188
189    if (hflg & HIST_LOAD) {
190        loadhist(*vp);
191        return;
192    }
193    else if (hflg & HIST_SAVE) {
194        rechist(*vp);
195        return;
196    }
197    if (*vp)
198        n = getn(*vp);
199    else {
200        n = getn(value(STRhistory));
201    }
202    dohist1(Histlist.Hnext, &n, hflg);
203}
204
205static void
206dohist1(hp, np, hflg)
207    struct Hist *hp;
208    int    *np, hflg;
209{
210    bool    print = (*np) > 0;
211
212    for (; hp != 0; hp = hp->Hnext) {
213        (*np)--;
214        hp->Href++;
215        if ((hflg & HIST_REV) == 0) {
216            dohist1(hp->Hnext, np, hflg);
217            if (print)
218                phist(hp, hflg);
219            return;
220        }
221        if (*np >= 0)
222            phist(hp, hflg);
223    }
224}
225
226static void
227phist(hp, hflg)
228    register struct Hist *hp;
229    int     hflg;
230{
231
232    if (hflg != HIST_ONLY) {
233        Char   *cp = str2short("%h\t%T\t%R\n");
234        Char buf[BUFSIZE];
235        struct varent *vp = adrof(STRhistory);
236
237        if (vp && vp->vec[0] && vp->vec[1])
238            cp = vp->vec[1];
239
240        tprintf(FMT_HISTORY, buf, cp, BUFSIZE, NULL, hp->Htime, (ptr_t) hp);
241        for (cp = buf; *cp;)
242            xputchar(*cp++);
243    }
244    else {
245        /*
246         * Make file entry with history time in format:
247         * "+NNNNNNNNNN" (10 digits, left padded with ascii '0')
248         */
249        xprintf("#+%010lu\n", hp->Htime);
250
251        if (HistLit && hp->histline)
252            xprintf("%S\n", hp->histline);
253        else
254            prlex(&hp->Hlex);
255    }
256}
257
258
259void
260fmthist(fmt, ptr, buf)
261    int fmt;
262    ptr_t ptr;
263    char *buf;
264{
265    struct Hist *hp = (struct Hist *) ptr;
266    switch (fmt) {
267    case 'h':
268        xsprintf(buf, "%6d", hp->Hnum);
269        break;
270    case 'R':
271        if (HistLit && hp->histline)
272            xsprintf(buf, "%S", hp->histline);
273        else {
274            Char ibuf[BUFSIZE], *ip;
275            char *p;
276            (void) sprlex(ibuf, &hp->Hlex);
277            for (p = buf, ip = ibuf; (*p++ = *ip++) != '\0'; )
278                continue;
279        }
280        break;
281    default:
282        buf[0] = '\0';
283        break;
284    }
285       
286}
287
288void
289rechist(fname)
290    Char *fname;
291{
292    Char    buf[BUFSIZE], hbuf[BUFSIZE];
293    int     fp, ftmp, oldidfds;
294    extern  int fast;
295    struct  varent *shist;
296    static Char   *dumphist[] = {STRhistory, STRmh, 0, 0};
297
298    if (!fast) {
299        /*
300         * If $savehist is just set, we use the value of $history
301         * else we use the value in $savehist
302         */
303        if ((shist = adrof(STRsavehist)) != NULL) {
304            if (shist->vec[0][0] != '\0')
305                (void) Strcpy(hbuf, shist->vec[0]);
306            else if ((shist = adrof(STRhistory)) != 0 &&
307                     shist->vec[0][0] != '\0')
308                (void) Strcpy(hbuf, shist->vec[0]);
309            else
310                return;
311        }
312        else
313            return;
314
315        if (fname == NULL)
316            if ((fname = value(STRhistfile)) == STRNULL) {
317                fname = Strcpy(buf, value(STRhome));
318                (void) Strcat(buf, &STRtildothist[1]);
319            }
320
321        fp = creat(short2str(fname), 0600);
322        if (fp == -1)
323            return;
324        oldidfds = didfds;
325        didfds = 0;
326        ftmp = SHOUT;
327        SHOUT = fp;
328        dumphist[2] = hbuf;
329        dohist(dumphist, NULL);
330        (void) close(fp);
331        SHOUT = ftmp;
332        didfds = oldidfds;
333    }
334}
335
336
337void
338loadhist(fname)
339    Char *fname;
340{
341    static Char   *loadhist_cmd[] = {STRsource, STRmh, NULL, NULL};
342
343    if (fname != NULL)
344        loadhist_cmd[2] = fname;
345    else if ((fname = value(STRhistfile)) != STRNULL)
346        loadhist_cmd[2] = fname;
347    else
348        loadhist_cmd[2] = STRtildothist;
349
350    dosource(loadhist_cmd, NULL);
351}
Note: See TracBrowser for help on using the repository browser.