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