v_put.c revision 19304
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_put.c	10.5 (Berkeley) 3/6/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 <limits.h>
22#include <stdio.h>
23
24#include "../common/common.h"
25#include "vi.h"
26
27static void	inc_buf __P((SCR *, VICMD *));
28
29/*
30 * v_Put -- [buffer]P
31 *	Insert the contents of the buffer before the cursor.
32 *
33 * PUBLIC: int v_Put __P((SCR *, VICMD *));
34 */
35int
36v_Put(sp, vp)
37	SCR *sp;
38	VICMD *vp;
39{
40	u_long cnt;
41
42	if (F_ISSET(vp, VC_ISDOT))
43		inc_buf(sp, vp);
44
45	/*
46	 * !!!
47	 * Historic vi did not support a count with the 'p' and 'P'
48	 * commands.  It's useful, so we do.
49	 */
50	for (cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
51		if (put(sp, NULL,
52		    F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
53		    &vp->m_start, &vp->m_final, 0))
54			return (1);
55		vp->m_start = vp->m_final;
56		if (INTERRUPTED(sp))
57			return (1);
58	}
59	return (0);
60}
61
62/*
63 * v_put -- [buffer]p
64 *	Insert the contents of the buffer after the cursor.
65 *
66 * PUBLIC: int v_put __P((SCR *, VICMD *));
67 */
68int
69v_put(sp, vp)
70	SCR *sp;
71	VICMD *vp;
72{
73	u_long cnt;
74
75	if (F_ISSET(vp, VC_ISDOT))
76		inc_buf(sp, vp);
77
78	/*
79	 * !!!
80	 * Historic vi did not support a count with the 'p' and 'P'
81	 * commands.  It's useful, so we do.
82	 */
83	for (cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
84		if (put(sp, NULL,
85		    F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
86		    &vp->m_start, &vp->m_final, 1))
87			return (1);
88		vp->m_start = vp->m_final;
89		if (INTERRUPTED(sp))
90			return (1);
91	}
92	return (0);
93}
94
95/*
96 * !!!
97 * Historical whackadoo.  The dot command `puts' the numbered buffer
98 * after the last one put.  For example, `"4p.' would put buffer #4
99 * and buffer #5.  If the user continued to enter '.', the #9 buffer
100 * would be repeatedly output.  This was not documented, and is a bit
101 * tricky to reconstruct.  Historical versions of vi also dropped the
102 * contents of the default buffer after each put, so after `"4p' the
103 * default buffer would be empty.  This makes no sense to me, so we
104 * don't bother.  Don't assume sequential order of numeric characters.
105 *
106 * And, if that weren't exciting enough, failed commands don't normally
107 * set the dot command.  Well, boys and girls, an exception is that
108 * the buffer increment gets done regardless of the success of the put.
109 */
110static void
111inc_buf(sp, vp)
112	SCR *sp;
113	VICMD *vp;
114{
115	CHAR_T v;
116
117	switch (vp->buffer) {
118	case '1':
119		v = '2';
120		break;
121	case '2':
122		v = '3';
123		break;
124	case '3':
125		v = '4';
126		break;
127	case '4':
128		v = '5';
129		break;
130	case '5':
131		v = '6';
132		break;
133	case '6':
134		v = '7';
135		break;
136	case '7':
137		v = '8';
138		break;
139	case '8':
140		v = '9';
141		break;
142	default:
143		return;
144	}
145	VIP(sp)->sdot.buffer = vp->buffer = v;
146}
147