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