Home | History | Annotate | Line # | Download | only in vi
v_put.c revision 1.1
      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
     13 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 ";
     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 
     27 static 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  */
     35 int
     36 v_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  */
     66 int
     67 v_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  */
    106 static void
    107 inc_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