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