source: trunk/third/nvi/vi/v_at.c @ 14302

Revision 14302, 2.7 KB checked in by ghudson, 25 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14301, which included commits to RCS files with non-trunk default branches.
Line 
1/*-
2 * Copyright (c) 1992, 1993, 1994
3 *      The Regents of the University of California.  All rights reserved.
4 * Copyright (c) 1992, 1993, 1994, 1995, 1996
5 *      Keith Bostic.  All rights reserved.
6 *
7 * See the LICENSE file for redistribution information.
8 */
9
10#include "config.h"
11
12#ifndef lint
13static const char sccsid[] = "@(#)v_at.c        10.8 (Berkeley) 4/27/96";
14#endif /* not lint */
15
16#include <sys/types.h>
17#include <sys/queue.h>
18#include <sys/time.h>
19
20#include <bitstring.h>
21#include <ctype.h>
22#include <limits.h>
23#include <stdio.h>
24
25#include "../common/common.h"
26#include "vi.h"
27
28/*
29 * v_at -- @
30 *      Execute a buffer.
31 *
32 * PUBLIC: int v_at __P((SCR *, VICMD *));
33 */
34int
35v_at(sp, vp)
36        SCR *sp;
37        VICMD *vp;
38{
39        CB *cbp;
40        CHAR_T name;
41        TEXT *tp;
42        size_t len;
43        char nbuf[20];
44
45        /*
46         * !!!
47         * Historically, [@*]<carriage-return> and [@*][@*] executed the most
48         * recently executed buffer in ex mode.  In vi mode, only @@ repeated
49         * the last buffer.  We change historic practice and make @* work from
50         * vi mode as well, it's simpler and more consistent.
51         *
52         * My intent is that *[buffer] will, in the future, pass the buffer to
53         * whatever interpreter is loaded.
54         */
55        name = F_ISSET(vp, VC_BUFFER) ? vp->buffer : '@';
56        if (name == '@' || name == '*') {
57                if (!F_ISSET(sp, SC_AT_SET)) {
58                        ex_emsg(sp, NULL, EXM_NOPREVBUF);
59                        return (1);
60                }
61                name = sp->at_lbuf;
62        }
63        F_SET(sp, SC_AT_SET);
64
65        CBNAME(sp, cbp, name);
66        if (cbp == NULL) {
67                ex_emsg(sp, KEY_NAME(sp, name), EXM_EMPTYBUF);
68                return (1);
69        }
70
71        /* Save for reuse. */
72        sp->at_lbuf = name;
73
74        /*
75         * The buffer is executed in vi mode, while in vi mode, so simply
76         * push it onto the terminal queue and continue.
77         *
78         * !!!
79         * Historic practice is that if the buffer was cut in line mode,
80         * <newlines> were appended to each line as it was pushed onto
81         * the stack.  If the buffer was cut in character mode, <newlines>
82         * were appended to all lines but the last one.
83         *
84         * XXX
85         * Historic practice is that execution of an @ buffer could be
86         * undone by a single 'u' command, i.e. the changes were grouped
87         * together.  We don't get this right; I'm waiting for the new DB
88         * logging code to be available.
89         */
90        for (tp = cbp->textq.cqh_last;
91            tp != (void *)&cbp->textq; tp = tp->q.cqe_prev)
92                if ((F_ISSET(cbp, CB_LMODE) ||
93                    tp->q.cqe_next != (void *)&cbp->textq) &&
94                    v_event_push(sp, NULL, "\n", 1, 0) ||
95                    v_event_push(sp, NULL, tp->lb, tp->len, 0))
96                        return (1);
97
98        /*
99         * !!!
100         * If any count was supplied, it applies to the first command in the
101         * at buffer.
102         */
103        if (F_ISSET(vp, VC_C1SET)) {
104                len = snprintf(nbuf, sizeof(nbuf), "%lu", vp->count);
105                if (v_event_push(sp, NULL, nbuf, len, 0))
106                        return (1);
107        }
108        return (0);
109}
Note: See TracBrowser for help on using the repository browser.