[mod.sources] v07i004: Vi front-end for remote editing, Part02/04

sources-request@mirror.UUCP (08/27/86)

Submitted by: Alan Klietz <ihnp4!dicome!mn-at1!alan>
Mod.sources: Volume 7, Issue 4
Archive-name: rvi/Part02

#!/bin/sh
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# Wrapped by mirror!rs on Wed Aug 27 00:06:55 EDT 1986

# Exit status; set to 1 on "wc" errors or if would overwrite.
STATUS=0
# Contents:  rv.h rv_cmd.c rv_delete.c rv_dummy.c rv_edit.c rv_fast.c
#	rv_fetch.c rv_flash.c rv_forback.c rv_getline.c rv_init.c
#	rv_input.c rv_join.c rv_main.c rv_mark.c rv_print_ln.c rv_quit.c
 
echo x - rv.h
if test -f rv.h ; then
    echo rv.h exists, putting output in $$rv.h
    OUT=$$rv.h
    STATUS=1
else
    OUT=rv.h
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv.h//'
XX#include <curses.h>
XX/*
XX *	Rvi - Portable distributed screen editor (DSE).
XX *	86/07/16.  Alan Klietz
XX *	Copyright (c) 1986, Research Equipment Incorporated
XX *                          Minnesota Supercomputer Center
XX *
XX * Permission is hereby granted to use this software on any computer system
XX * and to copy this software, including for purposes of redistribution, subject
XX * to the conditions that 
XX *
XX *  o  The full text of this copyright message is retained and prominently
XX *      displayed
XX *
XX *  o  No misrepresentation is made as to the authorship of this software
XX *
XX *  o  The software is not used for resale or direct commercial advantage
XX *
XX *  By copying, installing, or using this software, the user agrees to abide
XX *  by the above terms and agrees that the software is accepted on an "as is"
XX *  basis, WITHOUT WARRANTY expressed or implied, and relieves Research Equip-
XX *  ment Inc., its affiliates, officers, agents, and employees of any and all
XX *  liability, direct of consequential, resulting from copying, installing
XX *  or using this software.
XX */
XX#ifdef CRAY
XX#	define un_firstline	un_fline
XX#	define un_firstcol	un_fcol
XX#	define sc_firstline	sc_fline
XX#	define sc_firstcol	sc_fcol
XX#	define rv_scroll_backward	rv_scr_bk
XX#endif

XX/*
XX * Make initial program
XX * Alan Klietz, Nov 11, 1985.
XX */

XX/*
XX * Definitions
XX */
XX#ifndef CTRL
XX#define CTRL(c)	 ('c'&037)
XX#endif

XX#ifdef CRAY
XX#	define	INT	long  /* for speed */
XX#	define	boolean	long  /* for speed */
XX#else
XX#	define	INT	int
XX#	define	boolean	char
XX#endif

XX#ifdef USG
XX#define	zero(ptr, len)		memset(ptr, 0, len)
XX#define copy(to, from, len)	memcpy(to, from, len)
XX#endif

XX#define CURLINE			(stdscr->_cury)
XX#define CURCOLUMN		(stdscr->_curx)

XX#define COL_FIRST_NONWHITE	(-1023)	/* Column cookie for move_cursor(),
XX					   move to first non-white char */
XX#define COL_SAME		(-1024) /* Column cookie for move_cursor(),
XX					   move to same column as previous */

XX#define RV_TIMEOUT	20		/* Seconds until ed request times out */


XX/*
XX *  Five major structures,
XX * 	 struct line     -  A line of text.
XX *       struct yank     -  A yank buffer.
XX *	 struct undo     -  The undo-last-change structure. 
XX * 	 struct screen   -  The screen proper.
XX * 	 struct window   -  Sliding window into file. (Larger than screen)
XX *	 struct file	 -  General information about the file.
XX */

XXstruct li_line { /* A line of text */
XX	INT	li_width;	/* Width of this line */
XX	INT	li_segments;	/* Number of screen segments required */
XX	char	*li_text;	/* Pointer to actual text. (malloc) */
XX};

XXstruct ya_yank { /* A yank buffer */
XX	INT	ya_type;	/* YANK_COLS, YANK_SINGLE, or YANK_LINES */
XX	char	*ya_text;	/* Pointer to text (malloc) */
XX	INT	ya_width;	/* # of bytes yanked, if YANK_COLS or
XX				   YANK_SINGLE */
XX	INT	ya_numlines;	/* # of lines yanked, if YANK_LINES */
XX	boolean	ya_madefile;	/* TRUE if tempfile was created */
XX};
XX#define YANK_EMPTY  0
XX#define YANK_COLS   1
XX#define YANK_SINGLE 2
XX#define YANK_LINES  3
XX#define NUM_YANK_BUFS  38   /* 0-9, a-z, '.', and $ */


XXstruct un_undo { /* Structure for recalling last change */
XX	INT	un_firstline,		/* First line # of change */
XX		un_firstcol,		/* First column # of change */
XX		un_lastline,		/* Last line # of change */
XX		un_lastcol;		/* Last column # of change */
XX	boolean	un_validcol;		/* TRUE if first/last column defined */
XX	boolean	un_inserted;		/* TRUE if insertion was done */
XX	boolean	un_deleted;		/* TRUE if deleting was done */
XX};


XXstruct sc_screen { /* The screen proper */
XX	INT	sc_column;		/* Cursor position in current line */
XX	INT	sc_lineno;		/* Current line number */
XX	struct  li_line *sc_topline;	/* Ptr to first line on screen */
XX	struct	li_line	*sc_curline;	/* Ptr to current line on screen */
XX	struct  li_line *sc_botline;	/* Ptr to last line on screen */
XX	INT	sc_abovetop;		/* # of segments above the top line
XX					   after a downwards scroll */
XX	INT	sc_firstline,		/* First line # of operation */
XX		sc_firstcol,		/* First column # of operation */
XX		sc_lastline,		/* Last line # of operation */
XX		sc_lastcol;		/* Last column # of operation */
XX	boolean	sc_validcol;		/* TRUE if first/last column defined
XX					   above is valid */
XX	struct	li_line sc_origline;	/* Current line before modification, if
XX					   not modified text is null. */
XX};

XXstruct wi_window { /* Sliding window into file */
XX	struct	li_line	*wi_topline;	/* Ptr to first line in window */
XX	struct	li_line	*wi_botline;	/* Ptr to last line in window */
XX};

XXstruct fi_file { /* General information about the file */
XX	INT	fi_numlines;	/* # of lines in file */
XX	boolean	fi_modified;	/* TRUE if file modified */
XX	boolean	fi_sysv;	/* TRUE if ed has System V 'H' command */
XX	boolean	fi_cray;	/* TRUE if ed has Cray style error msgs */
XX	FILE	*fi_fpin;	/* Input file pointer from ed */
XX	FILE	*fi_fpout;	/* Output file pointer to ed */
XX	char	fi_name[128];	/* Name of edited file */
XX};

XX/*
XX * Global externals
XX */
XXextern struct	fi_file		file;
XXextern struct	wi_window	window;
XXextern struct	sc_screen	screen;
XXextern struct	li_line		*line_array;
XXextern struct	ya_yank		yank_array[NUM_YANK_BUFS];
XXextern struct	un_undo		undo;

XXextern char	**Argv;
XXextern boolean	use_linemode;	/* TRUE to use line mode in shell escapes */
XXextern boolean	ed_undo;	/* TRUE if last mod was direct ed cmd */
XXextern INT	errflag;	/* 1 if error in function call */
XXextern boolean	input_mode;	/* TRUE if input mode */
XXextern boolean	change_flag;	/* TRUE if change in progress */
XXextern boolean	replace_flag;	/* TRUE if R command */
XXextern char	*nextfile;	/* Next file to edit via 'n' cmd */
XXextern INT	nwin_lines;	/* Number of window lines */
XXextern boolean	opened_line;	/* TRUE if openline() called */
XXextern INT	yank_shift;	/* Shift offset for yank */
XXextern INT	yank_cmd;	/* "x yank buf command letter x. */

XXextern boolean	set_autoindent; /* TRUE if margins automatically indented */
XXextern INT	set_debug;	/* Debugging level */
XXextern boolean	set_list;	/* TRUE if list mode set (show tabs and EOL) */
XXextern boolean	set_fortran;	/* TRUE if Fortran-style tabs */
XXextern INT	set_scroll;	/* # of lines per ^D or ^U */
XXextern INT	set_tabstops;	/* Tabstop width */
XXextern boolean	set_timeout;	/* Timeout on function key */
XXextern INT	set_shiftwidth;	/* # of columns per tab char on input */
XXextern boolean	set_wrapscan;	/* TRUE if wrap around on string search */

XX#define NUM_WINDOW_LINES	nwin_lines

XXvoid		botprint();	   /* Print msg on bottom line */
XXvoid		change();	   /* Change text */
XXvoid		delete();	   /* Delete text */
XXvoid		dup_insert();	   /* Duplicate inserted text n times */
XXINT		file_column();	   /* Convert screen column to file column */
XXvoid		insert();	   /* Insert text into current line */
XXvoid		move_abs_cursor(); /* Move to (lineno, column) from anywhere */
XXvoid		move_cursor();	   /* Set cursor to (lineno, column).  Must
XX				      already be on screen. */
XXvoid		openline();	   /* Open new line in specified direction */
XXvoid		panic();	   /* Print msg and halt */
XXvoid		put();		   /* Put text in specified direction */
XXvoid		print_line();	   /* Print text at current cursor */
XXvoid		quit();
XXboolean		read_cmd();	   /* Read a command character */
XXboolean		recv_sync();	   /* Receive sync */
XXvoid		redraw_screen();   /* Update screen to curses */
XXINT		rv_getchar();
XXchar		*rv_getline();
XXvoid		save_Undo();	   /* Save current line to Undo buffer */
XXINT		screen_column();   /* Convert file column to screen column */
XXvoid		sizemsg();	   /* Print file size */
XXvoid		toss_undo();	   /* Forget last undo */
XXchar		*xalloc();	   /* Allocate memory */
XXvoid		xmit_curline();	   /* Transmit current line if modified */
XXvoid		xmit_ed();	   /* Transmit command */
XXvoid		xmit_sync();	   /* Transmit sync */
XXvoid		yank();		   /* Yank text */
@//E*O*F rv.h//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_cmd.c
if test -f rv_cmd.c ; then
    echo rv_cmd.c exists, putting output in $$rv_cmd.c
    OUT=$$rv_cmd.c
    STATUS=1
else
    OUT=rv_cmd.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_cmd.c//'
XX#include "rv.h"
XX#include <ctype.h>
XX/*
XX * rv_cmd.c  -  Main command loop
XX */

XXboolean	change_flag;		/* Used by word_scan() */

XXrv_cmd()
XX/*
XX * Loop and execute commands
XX * The screen is always refreshed afterwards.
XX */
XX{
XX	register struct sc_screen *sc;
XX	INT	i,j,k;	/* temp vars */
XX	INT     c;		/* Command character */
XX	boolean specified_count;/* TRUE if count was explicitly specified */
XX	INT     cmd_count;	/* Count, default 1 */
XX	void	read_where_mod(), where_mod(), rv_undo(), rv_dot(), rv_debug();
XX	void	rv_mark();
XX	boolean	search();

XX	sc = &screen;

XXfor (;;) {   /* Loop forever */
XX	errflag = 0;
XX	yank_cmd = ' ';
XX	specified_count = read_cmd(&c, &cmd_count);

XX	/*
XX	 * Main command switch
XX	 */
XX	switch (c) {

XXcase CTRL(L):
XX#ifdef USG
XXcase KEY_CLEAR:
XX#endif
XX	/*
XX	 * Clear and redisplay screen
XX	 */
XX	 clearok(curscr, TRUE);
XX	 break;

XXcase CTRL(R):
XX	/*
XX	 * Redraw screen
XX	 */
XX	 clearok(curscr, TRUE);
XX	 redraw_screen((struct li_line *)0);
XX	 break;

XXcase CTRL(E):
XX#ifdef USG
XXcase KEY_SF:
XX#endif
XX	/*
XX	 * Scroll up one line.  Leave cursor
XX	 * on same line, if possible.
XX	 */
XX	i = sc->sc_lineno + (CURLINE == 0 ? 1 : 0);
XX	j = sc->sc_column;
XX	/* Force scroll 1 line */
XX	move_abs_cursor((sc->sc_botline - sc->sc_curline) + sc->sc_lineno+1, 0);
XX	move_abs_cursor(i, j); /* Restore cursor */
XX	break;

XXcase CTRL(Y):
XX#ifdef USG
XXcase KEY_SR:
XX#endif
XX	/*
XX	 * Scroll down one line.  Leave cursor
XX	 * on same line, if possible.
XX	 */
XX	i = sc->sc_lineno - (CURLINE == LINES-2 ? 1 : 0);
XX	j = sc->sc_column;
XX	/* Scroll reverse scroll 1 line */
XX	move_abs_cursor(sc->sc_lineno-1 - (sc->sc_curline - sc->sc_topline), 0);
XX	move_abs_cursor(i, j);
XX	break;

XXcase 'h':
XXcase '\b':
XX#ifdef USG
XXcase KEY_LEFT:
XXcase KEY_BACKSPACE:
XX#endif
XX	/*
XX	 * Move cursor left 1 character
XX	 */
XX	move_cursor(sc->sc_lineno, sc->sc_column-cmd_count);
XX	break;

XXcase 'l':
XXcase ' ':
XX#ifdef USG
XXcase KEY_RIGHT:
XX#endif
XX	/*
XX	 * Move cursor right 1 character
XX	 */
XX	move_cursor(sc->sc_lineno, sc->sc_column+cmd_count);
XX	break;

XXcase 'k':
XXcase CTRL(P):
XX#ifdef USG
XXcase KEY_UP:
XX#endif
XX	/*
XX	 * Move cursor up 1 character
XX	 */
XX	move_abs_cursor(sc->sc_lineno-cmd_count, COL_SAME);
XX	break;

XXcase '-':
XX	/*
XX	 * Move to first nonwhite character on previous line
XX	 */
XX	 move_abs_cursor(sc->sc_lineno-cmd_count, COL_FIRST_NONWHITE);
XX	 break;

XXcase 'j':
XXcase '\n':
XXcase CTRL(N):
XX#ifdef USG
XXcase KEY_DOWN:
XX#endif
XX	/*
XX	 * Move cursor down 1 character
XX	 */
XX	move_abs_cursor(sc->sc_lineno+cmd_count, COL_SAME);
XX	break;

XXcase '\r':
XXcase '+':
XX	/*
XX	 * Move to first nonwhite character on next line
XX	 */
XX	move_abs_cursor(sc->sc_lineno+cmd_count, COL_FIRST_NONWHITE);
XX	break;

XXcase 'x':
XX#ifdef USG
XXcase KEY_DC:
XX#endif
XX	/*
XX	 * Delete character under cursor
XX	 */
XX	toss_undo();
XX	if (sc->sc_curline->li_width <= 0) {
XX		errflag = 1;
XX		flash();
XX		break;
XX	}
XX	sc->sc_validcol = TRUE;
XX	sc->sc_firstline = sc->sc_lineno;
XX	sc->sc_firstcol  = sc->sc_column;
XX	sc->sc_lastline = sc->sc_lineno;
XX	sc->sc_lastcol = sc->sc_column+cmd_count-1;
XX	if (sc->sc_lastcol >= sc->sc_curline->li_width)
XX		sc->sc_lastcol = sc->sc_curline->li_width-1;
XX	delete();
XX	break;

XXcase 'X':
XX	/*
XX	 * Delete character before cursor
XX	 */
XX	toss_undo();
XX	if (sc->sc_column <= 0) {
XX		errflag = 1;
XX		flash();
XX		break;
XX	}
XX	sc->sc_validcol = TRUE;
XX	sc->sc_lastline = sc->sc_lineno;
XX	sc->sc_lastcol = sc->sc_column-1;
XX	sc->sc_firstline = sc->sc_lineno;
XX	sc->sc_firstcol = sc->sc_column-cmd_count;
XX	if (sc->sc_firstcol < 0)
XX		sc->sc_firstcol = 0;
XX	delete();
XX	break;

XXcase CTRL(G):
XX	/*
XX	 * Print file size
XX	 */
XX	sizemsg();
XX	break;

XXcase CTRL(U):
XX#ifdef USG
XXcase KEY_PPAGE:
XX#endif
XX	/*
XX	 * Scroll screen up 1 page
XX	 */
XX	if (specified_count)
XX		set_scroll = cmd_count;
XX	else
XX		cmd_count = set_scroll;
XX	if (sc->sc_lineno <= 1) { /* If at top of file */
XX		errflag = 1;
XX		flash();
XX		break;
XX	}
XX	k = sc->sc_curline - sc->sc_topline;
XX	move_cursor(sc->sc_lineno - k, 0); /* Goto top of screen */
XX	for (i=0; i < cmd_count; ++i) {  /* Scrolling loop */
XX		if (sc->sc_lineno <= 1)  /* If past top of file */
XX			break;
XX		move_abs_cursor(sc->sc_lineno-1, 0); /* Scroll up */
XX		if (errflag)
XX			break;
XX	}
XX	if (i >= cmd_count) 
XX		move_abs_cursor(sc->sc_lineno + k, 0);  /* Move cursor back */
XX	move_cursor(sc->sc_lineno, COL_FIRST_NONWHITE); /* Set column */
XX	break;

XXcase CTRL(D):
XX#ifdef USG
XXcase KEY_NPAGE:
XX#endif
XX	/*
XX	 * Scroll screen down a page
XX	 */
XX	if (specified_count)
XX		set_scroll = cmd_count;
XX	else
XX		cmd_count = set_scroll;
XX	if (sc->sc_lineno >= file.fi_numlines) { /* If past bottom of file */
XX		errflag = 1;
XX		flash();
XX		break;
XX	}
XX	k = sc->sc_botline - sc->sc_curline;
XX	move_cursor(sc->sc_lineno + k, 0); /* Goto bottom of screen */
XX	for (i=0; i < cmd_count; ++i) { /* Scrolling loop */
XX		if (sc->sc_lineno >= file.fi_numlines) /* If past end of file */
XX			break;
XX		move_abs_cursor(sc->sc_lineno+1, 0); /* Scroll */
XX		if (errflag)
XX			break;
XX	}
XX	if (i >= cmd_count) 
XX		move_abs_cursor(sc->sc_lineno - k, 0);  /* Move cursor back */
XX	move_cursor(sc->sc_lineno, COL_FIRST_NONWHITE); /* Set column */
XX	break;

XXcase CTRL(B):
XX	/*
XX	 * Go back a page, with two
XX	 * lines of continuity
XX	 */
XX	if (sc->sc_lineno <= 1) { /* If past top of file */
XX		flash();
XX		errflag = 1;
XX		break;
XX	}
XX	clearok(curscr, TRUE);
XX	/* Go to top of screen */
XX	move_cursor(sc->sc_lineno - (sc->sc_curline - sc->sc_topline), 0);
XX	/* Go back LINES-2 */
XX	i = sc->sc_lineno - cmd_count*(LINES-2) + LINES/2;
XX	if (i <= 0)
XX		i = 1;
XX	move_abs_cursor(i, COL_FIRST_NONWHITE);
XX	break;

XXcase CTRL(F):
XX	/*
XX	 * Go forward a page, with two
XX	 * lines of continuity
XX	 */
XX	if (sc->sc_lineno >= file.fi_numlines) { /* if past end of file */
XX		flash();
XX		errflag = 1;
XX		break;
XX	}
XX	clearok(curscr, TRUE);
XX	/* Go to bottom of screen */
XX	move_cursor(sc->sc_lineno + (sc->sc_botline - sc->sc_curline), 0);
XX	/* Go forward LINES-2 */
XX	i = sc->sc_lineno + cmd_count*(LINES-2) - LINES/2;
XX	if (i > file.fi_numlines)
XX		i = file.fi_numlines;
XX	move_abs_cursor(i, COL_FIRST_NONWHITE);
XX	break;

XXcase 'M':
XX	/*
XX	 * Position cursor to middle line
XX	 */
XX	move_abs_cursor(sc->sc_lineno-(sc->sc_curline-sc->sc_topline)+LINES/2,
XX		COL_FIRST_NONWHITE);
XX	break;

XXcase 'Q':
XX	/*
XX	 * Drop into ed
XX	 */
XX	quit();
XX	break;

XXcase 'y':
XX	/*
XX	 * Yank
XX	 */
XX	toss_undo();
XX	read_where_mod(c, specified_count, cmd_count);
XX	if (errflag)
XX		break;
XX	yank();
XX	break;

XXcase 'Y':
XX	/*
XX	 * Yank lines
XX	 */
XX	toss_undo();
XX	sc->sc_validcol = FALSE;
XX	sc->sc_firstline = sc->sc_lineno;
XX	sc->sc_lastline = sc->sc_lineno + cmd_count-1;
XX	if (sc->sc_lastline > file.fi_numlines)
XX		sc->sc_lastline = file.fi_numlines;
XX	yank();
XX	break;

XXcase 'p':
XX	/*
XX	 * Put buffer
XX	 */
XX	undo.un_deleted = FALSE;
XX	j = sc->sc_lineno+1;
XX	put(1);
XX	if (cmd_count > 1)
XX		if (sc->sc_validcol)
XX			dup_insert(cmd_count);
XX		else {
XX			for (i=1; i < cmd_count; ++i)
XX				put(1);
XX			undo.un_firstline = j;
XX		}
XX	break;

XXcase 'P':
XX	/*
XX	 * Put buffer above cursor
XX	 */
XX	undo.un_deleted = FALSE;
XX	j = sc->sc_lineno-1;
XX	put(-1);
XX	if (cmd_count > 1)
XX		if (sc->sc_validcol)
XX			dup_insert(cmd_count);
XX		else {
XX			for (i=1; i < cmd_count; ++i)
XX				put(-1);
XX			undo.un_lastline = j;
XX		}
XX	break;

XXcase 'd':
XX	/*
XX	 * Delete
XX	 */
XX	toss_undo();
XX	read_where_mod(c, specified_count, cmd_count);
XX	if (errflag)
XX		break;
XX	delete();
XX	break;

XXcase 'D':
XX#ifdef USG
XXcase KEY_EOL:
XX#endif
XX	/*
XX	 * Delete rest of line
XX	 */
XX	toss_undo();
XX	sc->sc_validcol = TRUE;
XX	sc->sc_firstline = sc->sc_lineno;
XX	sc->sc_lastline = sc->sc_lineno;
XX	sc->sc_firstcol = sc->sc_column;
XX	sc->sc_lastcol = sc->sc_curline->li_width-1;
XX	delete();
XX	break;

XX#ifdef USG
XXcase KEY_DL:
XX#else
XXcase -2:
XX#endif
XX	/*
XX	 * Delete line
XX	 */
XX	toss_undo();
XX	sc->sc_validcol = FALSE;
XX	sc->sc_firstline = sc->sc_lineno;
XX	sc->sc_lastline = sc->sc_lineno;
XX	delete();
XX	break;

XXcase 'c':
XX	/*
XX	 * Change
XX	 */
XX	toss_undo();
XX	change_flag = TRUE;
XX	read_where_mod(c, specified_count, cmd_count);
XX	if (errflag)
XX		break;
XX	change();
XX	change_flag = FALSE;
XX	break;

XXcase 'C':
XX	/*
XX	 * Change rest of line
XX	 */
XX	toss_undo();
XX	sc->sc_firstline = sc->sc_lineno;
XX	sc->sc_lastline = sc->sc_lineno + cmd_count-1;
XX	if (sc->sc_lastline == sc->sc_firstline) {
XX		sc->sc_validcol = TRUE;
XX		sc->sc_firstline = sc->sc_lineno;
XX		sc->sc_firstcol = sc->sc_column;
XX		sc->sc_lastcol = sc->sc_curline->li_width-1;
XX	} else {
XX		sc->sc_validcol = FALSE;
XX		if (sc->sc_lastline > file.fi_numlines)
XX			sc->sc_lastline = file.fi_numlines;
XX	}
XX	change();
XX	break;
XX	
XXcase 'i':
XX#ifdef USG
XXcase KEY_IC:
XX#endif
XX	/*
XX	 * Insert before cursor
XX	 */
XX	toss_undo();
XX	sc->sc_validcol = TRUE;
XX	sc->sc_firstcol = sc->sc_column;
XX	sc->sc_lastcol = sc->sc_column-1;
XX	sc->sc_firstline = sc->sc_lastline = sc->sc_lineno;
XX	insert();
XX	if (cmd_count > 1)
XX		dup_insert(cmd_count);
XX	break;

XXcase 'I':
XX	/*
XX	 * Insert before first nonwhite char
XX	 */
XX	toss_undo();
XX	move_cursor(sc->sc_lineno, COL_FIRST_NONWHITE);
XX	sc->sc_validcol = TRUE;
XX	sc->sc_firstcol = sc->sc_column;
XX	sc->sc_lastcol = sc->sc_column-1;
XX	sc->sc_firstline = sc->sc_lastline = sc->sc_lineno;
XX	insert();
XX	if (cmd_count > 1)
XX		dup_insert(cmd_count);
XX	break;

XXcase 'a':
XX	/*
XX	 * Append after cursor
XX	 */
XX	toss_undo();
XX	if (sc->sc_curline->li_width > 0)
XX		sc->sc_column++;
XX	input_mode = TRUE; /* So move_cursor() will let us go past eol */
XX	move_cursor(sc->sc_lineno, sc->sc_column);
XX	sc->sc_validcol = TRUE;
XX	sc->sc_firstcol = sc->sc_column;
XX	sc->sc_lastcol = sc->sc_column-1;
XX	sc->sc_firstline = sc->sc_lastline = sc->sc_lineno;
XX	insert();
XX	if (cmd_count > 1)
XX		dup_insert(cmd_count);
XX	break;

XXcase 'A':
XX	/*
XX	 * Append at end of line
XX	 */
XX	toss_undo();
XX	sc->sc_column = sc->sc_curline->li_width;
XX	input_mode = TRUE; /* So move_cursor() will let us go past eol */
XX	move_cursor(sc->sc_lineno, sc->sc_column);
XX	sc->sc_validcol = TRUE;
XX	sc->sc_firstcol = sc->sc_column;
XX	sc->sc_lastcol = sc->sc_column-1;
XX	sc->sc_firstline = sc->sc_lastline = sc->sc_lineno;
XX	insert();
XX	if (cmd_count > 1)
XX		dup_insert(cmd_count);
XX	break;

XXcase 'R':
XX	/*
XX	 * Replace text
XX	 */
XX	toss_undo();
XX	sc->sc_validcol = TRUE;
XX	sc->sc_firstcol = sc->sc_column;
XX	sc->sc_lastcol = sc->sc_column-1;
XX	sc->sc_firstline = sc->sc_lastline = sc->sc_lineno;
XX	replace_flag = TRUE;
XX	insert();
XX	replace_flag = FALSE;
XX	if (cmd_count > 1)
XX		dup_insert(cmd_count);
XX	break;

XXcase '~':
XX	/*
XX	 * Switch case of char
XX	 */
XXcase 'r':
XX	/*
XX	 * Replace character under cursor
XX	 */
XX	toss_undo();
XX	if (sc->sc_curline->li_width <= 0) { /* If empty line */
XX		errflag = 1;
XX		flash();
XX		break;
XX	}
XX	if (c != '~')
XX		while ((i = getch()) == '\0')
XX			;
XX	else {
XX		i = sc->sc_curline->li_text[sc->sc_column];
XX		if (isupper(i))
XX			i = tolower(i);
XX		else if (islower(i))
XX			i = toupper(i);
XX	}
XX	save_Undo();
XX	sc->sc_validcol = TRUE;
XX	sc->sc_firstline = sc->sc_lastline = sc->sc_lineno;
XX	sc->sc_firstcol = sc->sc_lastcol = sc->sc_column;
XX	undo.un_deleted = TRUE;
XX	undo.un_inserted = TRUE;
XX	undo.un_validcol = sc->sc_validcol = TRUE;
XX	undo.un_firstline = undo.un_lastline = sc->sc_lineno;
XX	undo.un_firstcol = undo.un_lastcol = sc->sc_column;
XX	yank();
XX	sc->sc_curline->li_text[sc->sc_column] = i;
XX	redraw_curline(sc->sc_curline->li_text);
XX	move_cursor(sc->sc_lineno, sc->sc_column);
XX	if (cmd_count > 1)
XX		dup_insert(cmd_count);
XX	if (c == '~' && sc->sc_column < sc->sc_curline->li_width-1)
XX		move_cursor(sc->sc_lineno, sc->sc_column+1);
XX	break;

XXcase 's':
XX	/*
XX	 * Substitute 1 character
XX	 */
XX	toss_undo();
XX	sc->sc_validcol = TRUE;
XX	sc->sc_firstcol = sc->sc_column;
XX	sc->sc_lastcol = sc->sc_column+cmd_count-1;
XX	sc->sc_firstline = sc->sc_lastline = sc->sc_lineno;
XX	if (sc->sc_lastcol >= sc->sc_curline->li_width)
XX		sc->sc_lastcol = sc->sc_curline->li_width - 1;
XX	insert();
XX	break;

XXcase 'U':
XX	/*
XX	 * Undo changes to current line
XX	 */
XX	toss_undo();
XX	if (sc->sc_origline.li_text == NULL) { /* If no changes */
XX		errflag = 1;
XX		flash();
XX		break;
XX	}
XX	redraw_curline(sc->sc_origline.li_text);
XX	move_cursor(sc->sc_lineno, COL_FIRST_NONWHITE);
XX	sc->sc_origline.li_text = NULL;
XX	break;

XXcase 'u':
XX	/*
XX	 * General undo
XX	 */
XX	rv_undo();
XX	break;

XXcase '.':
XX	/*
XX	 * Repeat last change
XX	 */
XX	for (i=0; i < cmd_count; ++i)
XX		rv_dot();
XX	break;

XXcase 'J':
XX	/*
XX	 * Join lines
XX	 */
XX	toss_undo();
XX	join();
XX	break;


XXcase 'o':
XX	/*
XX	 * Open line after cursor
XX	 */
XX	toss_undo();
XX	openline(1);
XX	insert();
XX	break;

XXcase 'O':
XX#ifdef USG
XXcase KEY_IL:
XX#endif
XX	/*
XX	 * Open line before cursor
XX	 */
XX	toss_undo();
XX	openline(-1);
XX	insert();
XX	break;

XXcase 'S':
XX	/*
XX	 * Substitute lines
XX	 */
XX	toss_undo();
XX	sc->sc_validcol = FALSE;
XX	sc->sc_firstline = sc->sc_lineno;
XX	sc->sc_lastline = sc->sc_lineno+cmd_count-1;
XX	if (sc->sc_lastline > file.fi_numlines) {
XX		errflag = 1;
XX		flash();
XX		break;
XX	}
XX	change();
XX	break;

XXcase 'm':
XX	/*
XX	 * Mark text
XX	 */
XX	rv_mark();
XX	break;

XXcase ':':
XX	/*
XX	 * Line command
XX	 */
XX	mvaddch(LINES-1, 0, ':');
XX	rv_linecmd(rv_getline());
XX	break;

XXcase '&':
XX	/* 
XX	 * Repeat last s/../../
XX	 */
XX	rv_linecmd("s//%/");
XX	break;
XX	
XXcase CTRL(V):
XX	/*
XX	 * Display debug info
XX	 */
XX	rv_debug();
XX	break;

XXcase 'Z':
XX	/*
XX	 * Write and quit
XX	 */
XX	if (getch() != 'Z') {
XX		errflag = 1;
XX		flash();
XX		break;
XX	}
XX	rv_linecmd("wq");
XX	break;
XX		
XXdefault:
XX	/*
XX	 * A cursor movement command
XX	 */
XX	where_mod(c, specified_count, cmd_count, TRUE);
XX	if (errflag)
XX		break;
XX	/*
XX	 * Determine which row,col pair is the new location (first or last?)
XX	 */
XX	j = COL_FIRST_NONWHITE;
XX	if (sc->sc_firstline == sc->sc_lineno &&
XX	   (!sc->sc_validcol || sc->sc_firstcol == sc->sc_column)) {
XX		i = sc->sc_lastline;
XX		if (sc->sc_validcol)
XX			j = sc->sc_lastcol;
XX	} else {
XX		i = sc->sc_firstline;
XX		if (sc->sc_validcol)
XX			j = sc->sc_firstcol;
XX	}
XX	if (i == sc->sc_lineno) /* If already on line */
XX		move_cursor(i,j);
XX	else
XX		move_abs_cursor(i,j);
XX	break;
XX		

XX	} /* End of switch */

XX	opened_line = FALSE;

XX	fflush(file.fi_fpout);
XX	hitcr_continue();
XX	refresh();

XX}   /* End of loop */

XX}
@//E*O*F rv_cmd.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_delete.c
if test -f rv_delete.c ; then
    echo rv_delete.c exists, putting output in $$rv_delete.c
    OUT=$$rv_delete.c
    STATUS=1
else
    OUT=rv_delete.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_delete.c//'
XX#include "rv.h"

XXvoid delete()
XX/*
XX *  Delete - delete text
XX */
XX{
XX	register struct li_line	  *line;
XX	register struct sc_screen *sc;
XX	register struct wi_window *wi;
XX	void	delete_columns();
XX	INT seg;

XX	sc = &screen;
XX	wi = &window;

XX	file.fi_modified = TRUE;

XX	if (sc->sc_firstline != sc->sc_lastline || !sc->sc_validcol)
XX		xmit_curline();
XX	/*
XX	 * Save text in unnamed buffer for 'p' command.
XX	 */
XX	if (yank_cmd != ' ') { /* If user also specified buf */
XX		yank();	/* Yank into it too */
XX		yank_cmd = ' ';
XX	}
XX	yank(); /* Yank to the unnamed buf */
XX	undo.un_deleted = TRUE;
XX	undo.un_validcol = FALSE;
XX	undo.un_firstline = sc->sc_firstline;

XX	/*
XX	 * Three cases:  lines, columns, or both
XX	 */
XX	if (sc->sc_validcol) { /* If columns */
XX		if (sc->sc_firstline != sc->sc_lastline) { /* If both */
XX			botprint(TRUE,
XX			    "Cant delete columns within multiple lines yet.\n");
XX			return;
XX		}
XX		undo.un_validcol = TRUE;
XX		undo.un_firstcol = sc->sc_firstcol;
XX		delete_columns(sc->sc_firstcol, sc->sc_lastcol);
XX	}
XX	else { /* If lines */
XX		/*
XX		 * Store deleted lines in numbered (1-9) yank buffers
XX		 */
XX		++yank_shift;  /* Shift numbered bufs */
XX		yank_cmd = '1';
XX		yank(); /* Yank to new buf 1 */

XX		if (sc->sc_firstline == sc->sc_lastline) {
XX			/*
XX			 * Case 1 - delete single line
XX			 */
XX			xmit_ed("%dd\n", sc->sc_firstline);
XX			move_abs_cursor(sc->sc_lineno, COL_SAME);
XX			seg = sc->sc_curline->li_segments;
XX			if (sc->sc_curline->li_text) {
XX				free(sc->sc_curline->li_text);
XX				sc->sc_curline->li_text = NULL;
XX			}
XX			for (line=sc->sc_curline+1; line <= wi->wi_botline;
XX			   ++line) {
XX				/*
XX				 * Compact window
XX				 */
XX				(line-1)->li_text = line->li_text;
XX				(line-1)->li_width = line->li_width;
XX				(line-1)->li_segments = line->li_segments;
XX			}
XX			wi->wi_botline->li_text = NULL;
XX			wi->wi_botline--;
XX			sc->sc_botline--;
XX			file.fi_numlines--;
XX			if (sc->sc_curline > wi->wi_botline) {
XX				sc->sc_curline--;
XX				sc->sc_lineno--;
XX			}
XX			if (sc->sc_curline < sc->sc_topline) {
XX				sc->sc_abovetop = 0;
XX				sc->sc_topline = sc->sc_curline;
XX			} else {
XX				rv_fdeleteln(seg);
XX				move_cursor(sc->sc_lineno, COL_SAME);
XX				redraw_screen(sc->sc_botline+1);
XX				return;
XX			}
XX			move_cursor(sc->sc_lineno, COL_SAME);
XX			line = sc->sc_curline;
XX		} else {
XX			/*
XX			 * Delete multiple lines
XX			 */
XX			xmit_ed("%d,%dd\n",sc->sc_firstline,sc->sc_lastline);
XX			file.fi_numlines -= sc->sc_lastline-sc->sc_firstline+1;
XX			if (file.fi_numlines > 0)
XX				fetch_window(sc->sc_lineno - NUM_WINDOW_LINES/4
XX					- LINES/2 + 1, FALSE);
XX			else /* deleted all lines, wipe window clean */
XX				for (line = wi->wi_topline;
XX					    line <= wi->wi_botline; ++line) {
XX					free(line->li_text);
XX					line->li_text = NULL;
XX				}
XX			line = NULL;
XX		}
XX		if (file.fi_numlines <= 0) { 
XX			/*
XX			 * Deleted whole file.  Set up initial window
XX			 */
XX			wi->wi_topline = &line_array[NUM_WINDOW_LINES/4];
XX			wi->wi_botline = wi->wi_topline;
XX			wi->wi_topline->li_text = xalloc(1);
XX			wi->wi_topline->li_text[0] = '\0';
XX			wi->wi_topline->li_segments = 1;
XX			wi->wi_topline->li_width = 0;
XX			sc->sc_curline = wi->wi_topline;
XX			sc->sc_lineno = 1;
XX			sc->sc_column = 0;
XX			sc->sc_abovetop = 0;
XX			sc->sc_topline = sc->sc_botline = sc->sc_curline;
XX			file.fi_numlines = 1;
XX			line = NULL;
XX			xmit_ed("0a\n\n.\n");
XX			redraw_screen(line);
XX			move_cursor(sc->sc_lineno, COL_SAME);
XX			botprint(FALSE, "Empty file");
XX			hitcr_continue();
XX			return;
XX		}

XX		redraw_screen(line);
XX		move_cursor(sc->sc_lineno, COL_SAME);
XX		if (sc->sc_lastline - sc->sc_firstline > 1) {
XX			botprint(FALSE, "%d lines deleted",
XX				sc->sc_lastline - sc->sc_firstline + 1);
XX			hitcr_continue();
XX		}
XX	}
XX}
@//E*O*F rv_delete.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_dummy.c
if test -f rv_dummy.c ; then
    echo rv_dummy.c exists, putting output in $$rv_dummy.c
    OUT=$$rv_dummy.c
    STATUS=1
else
    OUT=rv_dummy.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_dummy.c//'
XX#include "rv.h"

XX#ifndef USG
XXerasechar()
XX{
XX	return CTRL(H);
XX}

XXkillchar()
XX{
XX	return CTRL(U);
XX}
XX#endif
@//E*O*F rv_dummy.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_edit.c
if test -f rv_edit.c ; then
    echo rv_edit.c exists, putting output in $$rv_edit.c
    OUT=$$rv_edit.c
    STATUS=1
else
    OUT=rv_edit.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_edit.c//'
XX#include "rv.h"
XX#include <ctype.h>

XXchar *nextfile;  /* Ptr to name of next file to edit */

XXextern 	char editlist[256]; /* List of files to edit */

XXvoid
XXedit(name)
XX/*
XX * Edit named file
XX * If null, edit next file in editlist[]
XX */
XXchar *name;
XX{
XX	register char *s;
XX	register INT c;
XX	char buf[256];
XX	extern alarmring();

XX	xmit_curline();

XX	if (nextfile == NULL)
XX		nextfile = editlist;

XX	if (name != NULL && *name != '\0') {
XX		strncpy(editlist, name, 255);
XX		nextfile = editlist;
XX	}

XX	s = nextfile;
XX	while (isspace(*s) && *s != '\0')
XX		++s;
XX	name = s;
XX	while (!isspace(*s) && *s != '\0')
XX		++s;
XX	if (*s != '\0') {
XX		*s++ = '\0';
XX		while (isspace(*s) && s != '\0')
XX			++s;
XX	}
XX	nextfile = s;

XX	if (name == NULL || *name == '\0')
XX		name = file.fi_name;

XX	if (name == NULL || *name == '\0' || strcmp(name, "/dev/null") == 0) {
XX		botprint(TRUE, "Missing file name");
XX		hitcr_continue();
XX		refresh();
XX		fetch_window(1, TRUE);
XX		move_abs_cursor(1, 0);
XX		return;
XX	}

XX	s = name+strlen(name)-1;
XX	if (*(s-1) == '.' && *s == 'f')
XX		set_fortran = TRUE;
XX	clear();
XX	botprint(FALSE, "\"%s\" %s", name, set_fortran ? "[fortran mode]" : "");
XX	hitcr_continue();
XX	refresh();
XX	xmit_sync();
XX	xmit_ed("e %s\n", name);
XX	(void) recv_sync(FALSE);
XX	alarm(RV_TIMEOUT);
XX	fgets(buf, 255, file.fi_fpin);
XX	if (buf[0] == '?' && (buf[1] == '\n' || buf[1] == ' ')) {
XX		/*
XX		 * Ed is complaining about something, but we don't
XX		 * know what it is.  It could be trying to edit a
XX		 * directory, or the old file may have been modified
XX		 * without saving the changes.
XX		 */
XX		/* Get err message from ed, if possible */
XX		if (file.fi_sysv && (!file.fi_cray || buf[1] != ' '))
XX			fgets(buf, 255, file.fi_fpin);
XX		alarm(0);
XX		if (!file.fi_modified && file.fi_numlines > 1) {
XX			if (file.fi_sysv)
XX				botprint(TRUE, "%s", buf);
XX			botprint(FALSE, "Are you sure?");
XX			refresh();
XX			while ((c = getch()) != 'y' && c != 'Y'
XX					&& c != 'n' && c != 'N')
XX				;
XX			hitcr_continue();
XX			if (c == 'n' || c == 'N') {
XX				if (file.fi_name[0] == '\0')
XX					strcpy(file.fi_name, ".");
XX				xmit_ed("f %s\n", file.fi_name);
XX				redraw_screen((struct li_line *)0);
XX				botprint(FALSE, "Continue editing \"%s\"",
XX					file.fi_name);
XX				return;
XX			}
XX		}
XX		alarm(RV_TIMEOUT);
XX		xmit_ed("e %s\n", name);
XX		fflush(file.fi_fpout);
XX		fgets(buf, 255, file.fi_fpin);
XX	}

XX	xmit_ed("f %s\n", name);
XX	if (name != file.fi_name)
XX		strncpy(file.fi_name, name, 126);
XX	if (buf[0] == '?') { /* If error */
XX		if (file.fi_sysv) {  /* Get err msg */
XX			if (!file.fi_cray || buf[1] != ' ')
XX				fgets(buf, 255, file.fi_fpin);
XX		} else
XX			strcpy(buf, "File not found");
XX		alarm(0);
XX		refresh();
XX		hitcr_continue();
XX		fetch_window(1, TRUE);
XX		botprint(TRUE, "%s", buf);
XX	} else {
XX		alarm(0);
XX		fetch_window(1, TRUE);
XX		file.fi_modified = FALSE;
XX		move_abs_cursor(1, 0);
XX		botprint(FALSE, "\"%s\"%s %d lines, %d characters", name,
XX			set_fortran ? " [fortran mode]" : "",
XX			file.fi_numlines, atoi(buf));
XX	} 
XX	move_abs_cursor(1, 0);
XX}
@//E*O*F rv_edit.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_fast.c
if test -f rv_fast.c ; then
    echo rv_fast.c exists, putting output in $$rv_fast.c
    OUT=$$rv_fast.c
    STATUS=1
else
    OUT=rv_fast.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_fast.c//'
XX#include "rv.h"

XX#ifndef USG
XXextern int _putchar();
XXstatic char *rCM, *rSC, *rRC, *rCS, *rAL, *rDL, *rSR;
XXstatic char tcbuf[256];
XXstatic char buf[4096];
XX#endif

XX/*
XX * Fast versions of curses routines
XX */

XXrv_finit()
XX{
XX#ifndef USG
XX	char *s;
XX	extern char *tgetstr();

XX	if (!ttytype || *ttytype == '\0')
XX		panic("Please set TERM to your terminal type.\n");
XX	s = tcbuf;
XX	tgetent(buf, ttytype);
XX	rSC = tgetstr("sc", &s);
XX	rCM = tgetstr("cm", &s);
XX	rRC = tgetstr("rc", &s);
XX	rCS = tgetstr("cs", &s);
XX	rAL = tgetstr("al", &s);
XX	rDL = tgetstr("dl", &s);
XX	rSR = tgetstr("sr", &s);

XX	if (!rCM)
XX		panic("Your terminal needs cursor motion capability");
XX#endif
XX}


XXstatic
XXunchange(win)
XX/*
XX * Reset window so it appears not to have changed
XX */
XXWINDOW *win;
XX{
XX	register INT	y, maxy;

XX	maxy = win->_maxy;
XX	for (y=0; y < maxy; ++y)
XX		win->_firstch[y] = _NOCHANGE;
XX}


XXrv_fscroll(cnt)
XX/*
XX * Fast scroll.  Cursor is assumed to be in the lower left corner.
XX */
XXINT cnt;
XX{
XX#ifdef USG
XX	for (; cnt > 0; --cnt) {
XX		if (scroll(stdscr) == ERR)
XX			return ERR;
XX	}
XX#else
XX	refresh();
XX	for (; cnt > 0; --cnt) {
XX		if (scroll(stdscr) == ERR)
XX			return ERR;
XX		if (scroll(curscr) == ERR)
XX			return ERR;
XX		curscr->_cury++;
XX	}
XX	unchange(stdscr);
XX#endif
XX	return OK;
XX}


XXrv_finsertln(cnt)
XX/*
XX * Fast line insert.
XX */
XXINT cnt;
XX{
XX#ifdef USG
XX	for (; cnt > 0; --cnt) {
XX		if (winsertln(stdscr) == ERR)
XX			return ERR;
XX	}
XX#else
XX	INT i;

XX	refresh();
XX	if (CURLINE == 0 && rSR)
XX		for (i=0; i < cnt; ++i)
XX			tputs(rSR, 1, _putchar);
XX	else if (rAL) 
XX		for (i=0; i < cnt; ++i)
XX			tputs(rAL, cnt - CURLINE, _putchar);
XX	else if (rCS) {
XX		tputs(rSC, 1, _putchar); /* Stupid chng scroll homes cursor */
XX		tputs(tgoto(rCS, LINES-1, CURLINE), 1, _putchar);
XX		tputs(rRC, 1, _putchar);
XX		for (i=0; i < cnt; ++i)
XX			tputs(rSR, 1, _putchar);
XX		tputs(tgoto(rCS, LINES-1, 0), 1, _putchar);
XX		tputs(rRC, 1, _putchar);
XX	} else
XX		panic("Need insert line capability");

XX	for (; cnt > 0; --cnt) {
XX		if (winsertln(stdscr) == ERR)
XX			return ERR;
XX		if (winsertln(curscr) == ERR)
XX			return ERR;
XX	}
XX	unchange(stdscr);
XX#endif
XX	return OK;
XX}


XXrv_fdeleteln(cnt)
XX/*
XX * Fast line delete.
XX */
XXINT cnt;
XX{
XX#ifdef USG
XX	for (; cnt > 0; --cnt) {
XX		if (wdeleteln(stdscr) == ERR)
XX			return ERR;
XX	}
XX#else
XX	INT i;

XX	refresh();
XX	if (rDL)
XX		for (i=0; i < cnt; ++i)
XX			tputs(rDL, cnt-CURLINE, _putchar);
XX	else if (rCS) {
XX		tputs(rSC, 1, _putchar); /* Stupid scroll homes cursor */
XX		tputs(tgoto(rCS, LINES-1, CURLINE), 1, _putchar);
XX		tputs(tgoto(rCM, 0, LINES-1), 1, _putchar);
XX		for (i=0; i < cnt; ++i)
XX			tputs("\n", 1, _putchar);
XX		tputs(tgoto(rCS, LINES-1, 0), 1, _putchar);
XX		tputs(rRC, 1, _putchar);
XX	} else
XX		panic("Need delete line capability");
XX	for (; cnt > 0; --cnt) {
XX		if (wdeleteln(stdscr) == ERR)
XX			return ERR;
XX		if (wdeleteln(curscr) == ERR)
XX			return ERR;
XX	}
XX	unchange(stdscr);
XX#endif

XX	return OK;
XX}
@//E*O*F rv_fast.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_fetch.c
if test -f rv_fetch.c ; then
    echo rv_fetch.c exists, putting output in $$rv_fetch.c
    OUT=$$rv_fetch.c
    STATUS=1
else
    OUT=rv_fetch.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_fetch.c//'
XX#include "rv.h"


XXvoid
XXfetch_window(first, redraw_flag)
XX/*
XX * Fetch a window starting at line 'first' in the file.
XX * Adjust current line if necessary
XX * Redraw screen
XX */
XXINT first;
XXboolean redraw_flag;	/* TRUE if redraw requested */
XX{
XX	register struct li_line   *line;
XX	register struct sc_screen *sc;
XX	register struct wi_window *wi;
XX	char buf[512];
XX	INT	last, i, j;
XX	extern alarmring();

XX	sc = &screen;
XX	wi = &window;

XX	xmit_curline();
XX	/*
XX	 * Free old window's text
XX	 */
XX	if (file.fi_numlines > 0)
XX		for (line=wi->wi_topline; line <= wi->wi_botline; ++line)
XX			if (line->li_text) {
XX				free(line->li_text);
XX				line->li_text = NULL;
XX			}
XX	
XX	/*
XX	 * Set first/last lines
XX	 */
XX	if (first < 1)
XX		first = 1;
XX	last = first + NUM_WINDOW_LINES-1;
XX	if (last > file.fi_numlines)
XX		last = file.fi_numlines;

XXretry:
XX	/*
XX	 * Send request to ed
XX	 */
XX	xmit_sync();
XX	xmit_ed("$=\n");
XX	xmit_ed("%d,%dp\n", first, last);

XX	(void) recv_sync(FALSE);
XX	alarm(RV_TIMEOUT);
XX	(void) fgets(buf, 511, file.fi_fpin);

XX	if ((i = atoi(buf)) == 0 && buf[0] != '0')
XX		panic("$= request to ed failed\n\n");

XX	if (i <= 0) {
XX		/*
XX		 * Deleted whole file
XX		 */
XX		wi->wi_topline = &line_array[NUM_WINDOW_LINES/4];
XX		wi->wi_botline = wi->wi_topline;
XX		wi->wi_topline->li_text = xalloc(1);
XX		wi->wi_topline->li_text[0] = '\0';
XX		wi->wi_topline->li_segments = 1;
XX		wi->wi_topline->li_width = 0;
XX		sc->sc_curline = wi->wi_topline;
XX		sc->sc_lineno = 1;
XX		sc->sc_column = 0;
XX		sc->sc_abovetop = 0;
XX		sc->sc_topline = sc->sc_botline = sc->sc_curline;
XX		file.fi_numlines = 1;
XX		alarm(0);
XX		redraw_screen((struct li_line *)0);
XX		xmit_ed("0a\n\n.\n");
XX		return;
XX	}

XX	file.fi_numlines = i;
XX	if (last > i) {
XX		/*
XX		 * The file shrunk below our requested window size.
XX		 * Probably due to a .,$d command.
XX		 *
XX		 * Shift the window towards the top of whatever
XX		 * text is left.
XX		 */
XX		last = i;
XX		first = last - (NUM_WINDOW_LINES+1);
XX		if (first < 1)
XX			first = 1;
XX		goto retry;
XX	}
XX	/*
XX	 * See if file grew and window can be extended
XX	 */
XX	j = first + NUM_WINDOW_LINES-1;
XX	if (j > file.fi_numlines)
XX		j = file.fi_numlines;
XX	if (j != last) {
XX		last = j;
XX		goto retry;
XX	}

XX	/*
XX	 * Read in window lines
XX	 */
XX	line = &line_array[0];
XX	for (i=first; i <= last; ++i, ++line) {
XX		if (fgets(buf, 511, file.fi_fpin) == NULL)
XX			panic("Error during input from ed\n\n");
XX		/*
XX		 * Strip trailing \n
XX		 */
XX		if ((j = strlen(buf)) > 0 && buf[j-1] == '\n')
XX			buf[--j] = '\0';
XX		line->li_text = xalloc(j+1);
XX		strcpy(line->li_text, buf);
XX		line->li_width = j;
XX		line->li_segments = 1 + (screen_column(buf, j-1)+set_list)/COLS;
XX	}
XX	alarm(0);

XX	wi->wi_topline = &line_array[0];
XX	wi->wi_botline = line-1;
XX	sc->sc_abovetop = 0;
XX	if (sc->sc_lineno >= first && sc->sc_lineno <= last) {
XX		/*
XX		 * Case 1 - Current line is still in window
XX		 *          Calculate curline, topline
XX		 */
XX		line = wi->wi_topline + (sc->sc_lineno - first);
XX		i = sc->sc_curline - sc->sc_topline;
XX		if (sc->sc_lineno - i < first)
XX			sc->sc_topline = wi->wi_topline;
XX		else
XX			sc->sc_topline = line - i;
XX		sc->sc_curline = line;
XX	} else {
XX		/*
XX		 * Case 2 - Current line outside window
XX		 *          Choose new current line, topline
XX		 */
XX		line = wi->wi_topline + NUM_WINDOW_LINES/4 + LINES/2 - 1;
XX		if (line > wi->wi_botline)
XX			line = wi->wi_botline;
XX		sc->sc_topline = line - (LINES/2 - 1);
XX		if (sc->sc_topline < wi->wi_topline ||
XX		    sc->sc_topline > wi->wi_botline)
XX			sc->sc_topline = wi->wi_topline;
XX		sc->sc_lineno = first + (line - wi->wi_topline);
XX		sc->sc_curline = line;
XX	}

XX	if (redraw_flag) { /* If redraw requested */
XX		redraw_screen((struct li_line *)0);
XX		move_cursor(sc->sc_lineno, COL_FIRST_NONWHITE);
XX	} else {
XX		/*
XX		 * Compute bottom line
XX		 */
XX		line = sc->sc_topline;
XX		for (j = line->li_segments; j < LINES; j += line->li_segments) {
XX			++line;
XX			if (line > wi->wi_botline)
XX				break;
XX		}
XX		sc->sc_botline = line-1;
XX	}
XX}
@//E*O*F rv_fetch.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_flash.c
if test -f rv_flash.c ; then
    echo rv_flash.c exists, putting output in $$rv_flash.c
    OUT=$$rv_flash.c
    STATUS=1
else
    OUT=rv_flash.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_flash.c//'
XX#include "rv.h"

XX/*
XX * Simulate flash() on non-USG curses
XX */

XX#ifndef USG
XXextern int _putchar();
XXvoid
XXflash()
XX{
XX	static INT once;
XX	static char flashstr[80];
XX	char *tgetstr(), *s;

XX	if (!once) {
XX		++once;
XX		s = flashstr;
XX		if (tgetstr("vb", &s) == NULL) {
XX			s = flashstr;
XX			if (tgetstr("bl", &s) == NULL)
XX				strcpy(flashstr, "\007");
XX		}
XX	}

XX	_puts(flashstr);
XX}
XX#endif !USG
@//E*O*F rv_flash.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_forback.c
if test -f rv_forback.c ; then
    echo rv_forback.c exists, putting output in $$rv_forback.c
    OUT=$$rv_forback.c
    STATUS=1
else
    OUT=rv_forback.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_forback.c//'
XX#include "rv.h"

XXstatic INT direction = 1;
XXstatic char search_char = ' ';
XXstatic boolean incl_char = TRUE;

XXboolean
XXforward_back(c, cmd_count)
XX/*
XX * Scan forward and backward in line for character
XX */
XXINT c;
XXINT cmd_count;
XX{
XX	register struct sc_screen *sc;
XX	register char *s;
XX	register INT i;

XX	sc = &screen;
XX	s = sc->sc_curline->li_text;

XX	switch (c) {
XXcase 'f':
XX	/*
XX	 * Search forward to char
XX	 */
XX	search_char = getch();
XX	direction = 1;
XX	incl_char = TRUE;
XX	break;

XXcase 'F':
XX	/*
XX	 * Search backward to char
XX	 */
XX	search_char = getch();
XX	direction = -1;
XX	incl_char = TRUE;
XX	break;

XXcase 't':
XX	/*
XX	 * Search forward upto char
XX	 */
XX	search_char = getch();
XX	direction = 1;
XX	incl_char = FALSE;
XX	break;

XXcase 'T':
XX	/*
XX	 * Search backward upto char
XX	 */
XX	search_char = getch();
XX	direction = -1;
XX	incl_char = FALSE;
XX	break;

XXcase ';':
XX	/*
XX	 * Repeat last
XX	 */
XX	break;

XXcase ',':
XX	/*
XX	 * Repeat last, opposite direction
XX	 */
XX	direction = (direction >= 0 ? -1 : 1);
XX	break;

XXdefault:
XX	return FALSE;

XX	} /* End switch */


XX	i = sc->sc_column;
XX	sc->sc_validcol = TRUE;
XX	for (; cmd_count > 0; --cmd_count) {
XX		i += direction;
XX		while (s[i] != search_char) {
XX			if (i < 0 || s[i] == '\0')
XX				return FALSE;
XX			i += direction;
XX		}
XX	}

XX	if (direction >= 0) {
XX		sc->sc_lastcol = i;
XX		if (!incl_char)
XX			sc->sc_lastcol--;
XX	} else {
XX		sc->sc_lastcol--;
XX		sc->sc_firstcol = i;
XX		if (!incl_char)
XX			sc->sc_firstcol++;
XX	}

XX	return (sc->sc_firstcol <= sc->sc_lastcol);
XX}
@//E*O*F rv_forback.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_getline.c
if test -f rv_getline.c ; then
    echo rv_getline.c exists, putting output in $$rv_getline.c
    OUT=$$rv_getline.c
    STATUS=1
else
    OUT=rv_getline.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_getline.c//'
XX#include "rv.h"
XX#include <ctype.h>

XXextern boolean did_botprint;  /* Used by hitcr_continue() */
XXextern boolean scrolled;      /* Used by hitcr_continue() */
XXextern boolean superquote;    /* Set by rv_getchar() */

XXstatic char buf[256];

XXchar *
XXrv_getline()
XX/*
XX * Read input line
XX * Returns a static buffer, else NULL
XX */
XX{
XX	char *s, ch;
XX	INT savecol, saverow;

XX	s = buf;
XX	strncpy(buf, "", 256);  /* Zero out buf */
XX	savecol = CURCOLUMN;
XX	saverow = CURLINE;
XX	hitcr_continue();
XX	clrtobot();
XX	move(saverow, savecol);  /* Because clrtobot homes the cursor in 4bsd */
XX	did_botprint = TRUE;

XX	for (;;) {
XX		ch = rv_getchar();
XX		if (!superquote) {
XX			if (ch == erasechar())
XX				ch = '\b';
XX			if (ch == killchar())
XX				ch = CTRL(X);
XX			switch (ch) {
XXcase '\b':
XX		/*
XX		 * Backspace
XX		 */
XX		if (s-- <= buf) {
XX			if (screen_column(buf, strlen(buf)) >= COLS-1)
XX				scrolled = TRUE;
XX			hitcr_continue();
XX			move_cursor(screen.sc_lineno, screen.sc_column);
XX			return NULL;
XX		}
XX		move(CURLINE, CURCOLUMN-1);
XX		if (*s < ' ' || *s > '~')
XX			move(CURLINE, CURCOLUMN-1);
XX		clrtoeol();
XX		break;

XXcase CTRL(X):
XX		/*
XX		 * Line kill
XX		 */
XX		s = buf;
XX		move(saverow, savecol);
XX		clrtobot();
XX		move(saverow, savecol);
XX		break;

XXcase '\t':
XX		/*
XX		 * Tab
XX		 */
XX		addch('^');
XX		addch('I');
XX		*s++ = ch;
XX		break;

XXcase '\r':
XXcase '\n':
XXcase CTRL([):
XX		/*
XX		 * End of line 
XX		 */
XX		if (screen_column(buf, strlen(buf)) >= COLS-1)
XX			scrolled = TRUE;
XX		*s = '\0';
XX		hitcr_continue();
XX		move_cursor(screen.sc_lineno, screen.sc_column);
XX		return buf;

XXdefault:
XX		addch(ch);
XX		*s++ = ch;
XX		break;

XX			} /* End switch */
XX		} else {
XX			addch(ch);
XX			*s++ = ch;
XX		}

XX		if (buf-s >= 250) { /* If end of buffer */
XX			scrolled = TRUE;
XX			*s = '\0';
XX			hitcr_continue();
XX			move_cursor(screen.sc_lineno, screen.sc_column);
XX			return buf;
XX		}
XX	}
XX}
@//E*O*F rv_getline.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_init.c
if test -f rv_init.c ; then
    echo rv_init.c exists, putting output in $$rv_init.c
    OUT=$$rv_init.c
    STATUS=1
else
    OUT=rv_init.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_init.c//'
XX#include "rv.h"
XX#include <signal.h>

XX#ifdef CURSHDR
XX#include "curshdr.h"
XX#endif

XXextern char editlist[256]; /* List of files to edit */

XXvoid
XXed_init()
XX/*
XX * Initialize access to ed
XX */
XX{
XX	INT in, out;
XX	int pipebroke(), alarmring();
XX	boolean synced = 0;
XX	char buf[128];

XX	alarm(RV_TIMEOUT);
XX	(void) signal(SIGPIPE, pipebroke);
XX	(void) signal(SIGALRM, alarmring);
XX	/*
XX	 * Open pipe streams to ed
XX	 */
XX	if ((in = atoi(Argv[1])) <= 0 || (out = atoi(Argv[2])) <= 0)
XX		panic("Bad pipe descriptors\n\n");
XX	if ((file.fi_fpin  = fdopen(in , "r")) == NULL ||
XX	    (file.fi_fpout = fdopen(out, "w")) == NULL)
XX		panic("Bad fdopen on pipe stream\n\n");

XX	/*
XX	 * All versions of ed are not alike.  In particular the format
XX	 * of error messages widely varies between systems.  (See the
XX	 * 'H' command in System V).
XX	 *
XX	 * Rvi supports three versions of ed: System V, 4bsd, and Cray.
XX	 * This piece of code attempts to intuit which version of ed we
XX	 * have here.
XX	 */

XX	if (fputs("zzz\n$=\nH\n$=\n", file.fi_fpout) == NULL)
XX		panic("Cannot write to ed\n\n");
XX	fflush(file.fi_fpout);

XX	for (;;) {
XX		if (fgets(buf, 126, file.fi_fpin) == NULL)
XX			panic("Cannot read from ed\n\n");
XX		if (set_debug > 1)
XX			fprintf(stderr, "1 %s", buf);
XX		if (synced) {
XX			if (buf[0] != '?') {
XX				/*
XX				 * If the H command is supported
XX				 */
XX				file.fi_sysv = TRUE;
XX				/*
XX				 * The H command is a toggle.  Force it "on"
XX				 * if we just toggled it off.
XX				 */
XX				if (atoi(buf) != 0 || buf[0] == '0')
XX					fputs("H\n", file.fi_fpout);
XX			}
XX			break;
XX		}
XX		if (atoi(buf) != 0 || buf[0] == '0')
XX			synced = TRUE;
XX	}

XX	/* One line of output waiting to be read at this point */

XX	if (set_debug > 1)
XX		fprintf(stderr, "sysv=%d\n", file.fi_sysv);

XX	if (file.fi_sysv) {
XX		/*
XX		 * The Cray version of ed is based on SystemV, however
XX		 * the format of error messages generated by the 'H' command
XX		 * are not compatible.
XX		 *
XX		 *
XX		 * System V format:
XX		 *
XX		 * ?
XX		 * error message
XX		 *
XX		 *
XX		 * Cray format:
XX		 *
XX		 * ? error message
XX		 *
XX		 */
XX		fputs("zzz\nf\n", file.fi_fpout);
XX		fflush(file.fi_fpout);
XX		(void) fgets(buf, 126, file.fi_fpin);
XX		if (set_debug > 1)
XX			fprintf(stderr, "2 %s", buf);
XX		/*
XX		 * Skip last 'H' response
XX		 */
XX		if (fgets(buf, 126, file.fi_fpin) == NULL)
XX			panic("Cannot read from ed\n\n");
XX		if (set_debug > 1)
XX			fprintf(stderr, "3 %s", buf);
XX		if (buf[0] != '?')
XX			panic("Sync problem in ed_init\n\n");
XX		if (buf[1] != '\n')
XX			file.fi_cray = TRUE;
XX		else {
XX			(void) fgets(buf, 126, file.fi_fpin);
XX			if (set_debug > 1)
XX				fprintf(stderr, "4 %s", buf);
XX		}
XX	} else { /* 4.2bsd */
XX		fputs("f\n", file.fi_fpout);
XX		fflush(file.fi_fpout);
XX		(void) fgets(buf, 126, file.fi_fpin);
XX		if (set_debug > 1)
XX			fprintf(stderr, "5 %s", buf);
XX	}

XX	if (set_debug > 1) 
XX		fprintf(stderr, "cray=%d\n", file.fi_cray);
XX	/*
XX	 * Get current file name (used in syncs)
XX	 */
XX	if (fgets(buf, 126, file.fi_fpin) == NULL)
XX		panic("Cannot read from ed\n\n");
XX	buf[strlen(buf)-1] = '\0'; /* Strip trailing \n */
XX	if (buf[0] == '\0' || buf[0] == ' ') { /* If no file name */
XX		strcpy(buf, "/dev/null");
XX		fputs("f /dev/null\n", file.fi_fpout);
XX	}
XX	if (set_debug > 1)
XX		fprintf(stderr, "name: %s.\n", buf);
XX	strcpy(file.fi_name, buf);
XX	
XX	alarm(0);
XX	signal(SIGINT, quit);
XX	nextfile = editlist;
XX	if (editlist[0] != '\0')
XX		edit(NULL);
XX	else {
XX		fetch_window(1, TRUE);
XX		sizemsg();
XX	}
XX}

XXpipebroke()
XX{
XX	panic("Broken pipe\n\n");
XX	/*NOTREACHED*/
XX}

XXalarmring()
XX{
XX	panic("Connection timed out - ed now has control.\n\n");
XX	/*NOTREACHED*/
XX}
XX	

XXinitialize()
XX{
XX	char *s;
XX	extern char *getenv();

XX	initscr();
XX	noecho();
XX#ifdef CRAY
XX	nl();
XX#else
XX	nonl();
XX#endif

XX	scrollok(stdscr, TRUE);
XX	scrollok(curscr, TRUE);

XX#ifdef USG
XX	idlok(stdscr, TRUE);
XX	idlok(curscr, TRUE);
XX	cbreak();
XX	keypad(stdscr, set_timeout ? 1 : 2);

XX# ifdef CURSHDR
XX	/*
XX	 * Kludge - force VT100 terminals to emulate insert/delete line
XX	 * with scrolling windows.  I think this looks better.  AEK
XX	 */
XX	if (SP->term_costs.ilfixed < INFINITY && SP->term_costs.ilfixed > 10)
XX		SP->term_costs.ilfixed = 10;
XX# endif CURSHDR
XX#else
XX	crmode();
XX#endif !USG

XX	/*
XX	 * Allocate the window buffer
XX	 */
XX	nwin_lines = LINES*3+4;
XX	line_array = (struct li_line *) xalloc(sizeof(struct li_line) * 
XX		(nwin_lines + 6));
XX	/*
XX	 * Kludge: leave two lines unused below line_addr so that pointer
XX	 * comparisons on segmented architectures (e.g. iAPX286) wont
XX	 * wrap around to 0xffff
XX	 */
XX	line_array += 2;

XX	rv_finit();

XX	set_scroll = LINES/2;
XX	clear();
XX	ed_init();
XX	if ((s = getenv("RVINIT")) != NULL)
XX		rv_linecmd(s);
XX	refresh();
XX}
@//E*O*F rv_init.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_input.c
if test -f rv_input.c ; then
    echo rv_input.c exists, putting output in $$rv_input.c
    OUT=$$rv_input.c
    STATUS=1
else
    OUT=rv_input.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_input.c//'
XX#include "rv.h"

XX#ifdef CRAY
XX#define cmd_countptr   c_countptr
XX#endif

XX/*
XX * Read a command character, possibly prefixed with a count.
XX *    c               - Command character
XX *    cmd_count       - Command count, default 1.
XX *
XX *    Returns TRUE if an explicit count was specified
XX */
XXboolean read_cmd(cptr, cmd_countptr)
XXINT  *cptr;
XXINT  *cmd_countptr;
XX{
XX	register	INT	c;
XX	register	INT	cmd_count;
XX	boolean		specified_count;

XX	cmd_count = 0;
XX	specified_count = FALSE;
XX	do { 
XX		c = getch();
XX		if (c == ERR || c == EOF)
XX			quit();
XX				
XX		if (c != '0') /* '0' is a command! */
XX			while (c >= '0' && c <= '9') {
XX				specified_count = TRUE;
XX				cmd_count = cmd_count * 10 + c - '0';
XX				c = getch();
XX			}
XX		if (c == '\"') {
XX			yank_cmd = getch();
XX			(void) char_to_yank(yank_cmd);
XX			if (errflag) /* If bad "x yank letter */
XX				break;
XX		}
XX	} while (c == '\"');

XX	if (!specified_count)
XX		*cmd_countptr = 1;  /* default */
XX	else
XX		*cmd_countptr = cmd_count;
XX	*cptr = c;
XX	return(specified_count);
XX}
@//E*O*F rv_input.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_join.c
if test -f rv_join.c ; then
    echo rv_join.c exists, putting output in $$rv_join.c
    OUT=$$rv_join.c
    STATUS=1
else
    OUT=rv_join.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_join.c//'
XX#include "rv.h"
XX#include <ctype.h>

XXvoid
XXjoin()
XX/*
XX *  Join current line with line following
XX */
XX{
XX	register struct li_line	  *line, *line2;
XX	register struct sc_screen *sc;
XX	register char *s, *s2;
XX	struct wi_window *wi;
XX	struct ya_yank	 *yk;
XX	INT joincol, bottom;
XX	char *txt;

XX	sc = &screen;
XX	wi = &window;

XX	file.fi_modified = TRUE;
XX	line = sc->sc_curline;
XX	line2 = line+1;
XX	if (sc->sc_lineno >= file.fi_numlines) {
XX		flash();
XX		errflag = 1;
XX		return;
XX	}

XX	if (line2 > wi->wi_botline) {
XX		fetch_window(sc->sc_lineno - NUM_WINDOW_LINES/4 - LINES/2 + 1,
XX			TRUE);
XX		join();
XX		return;
XX	}

XX	txt = xalloc(strlen(line->li_text) + strlen(line2->li_text) + 3);
XX	strcpy(txt, line->li_text);
XX	joincol = line->li_width;
XX	/*
XX	 * Add a space between lines, if not already there
XX	 * Add 2 spaces after a period
XX	 */
XX	s = txt + line->li_width;
XX	if (line->li_width > 0 && !isspace(*(s-1))) {
XX		if (*(s-1) == '.')
XX			*s++ = ' ';
XX		*s++ = ' ';
XX	}

XX	/*
XX	 * Strip leading spaces from second line
XX	 */
XX	s2 = line2->li_text;
XX	while (isspace(*s2) && *s2 != '\0')
XX		++s2;
XX	
XX	/*
XX	 * Append second line to first
XX	 */
XX	while (*s2 != '\0')
XX		*s++ = *s2++;
XX	*s = '\0';
XX	openline(-1);
XX	redraw_curline(txt);
XX	free(txt);

XX	/*
XX	 * Delete old lines
XX	 * Yank manually to prevent a fetch_window
XX	 */
XX	move_abs_cursor(sc->sc_lineno+1, 0);
XX	sc->sc_validcol = FALSE;
XX	sc->sc_firstline = sc->sc_lineno;
XX	sc->sc_lastline = sc->sc_firstline+1;
XX	yank_cmd = ' ';
XX	yank();
XX	yk = &yank_array[0];
XX	sc->sc_lastline = sc->sc_firstline;
XX	bottom = (sc->sc_lineno >= file.fi_numlines-1);
XX	delete();
XX	delete();
XX	yk->ya_type = YANK_LINES;
XX	yk->ya_width = 0;
XX	yk->ya_numlines = 2;
XX	if (yk->ya_text) {
XX		free(yk->ya_text);
XX		yk->ya_text = NULL;
XX	}

XX	/*
XX	 * Put cursor on spot between joined lines
XX	 */
XX	if (!bottom)
XX		move_cursor(sc->sc_lineno-1, joincol);
XX	else
XX		move_cursor(sc->sc_lineno, joincol);
XX	undo.un_firstline = sc->sc_lineno; /* Bashed by delete() */
XX	save_Undo();
XX}
@//E*O*F rv_join.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_main.c
if test -f rv_main.c ; then
    echo rv_main.c exists, putting output in $$rv_main.c
    OUT=$$rv_main.c
    STATUS=1
else
    OUT=rv_main.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_main.c//'
XX#include "rv.h"
XX/*
XX *	Rvi - Portable distributed screen editor (DSE).
XX *	86/07/16.  Alan Klietz
XX *	Copyright (c) 1986, Research Equipment Incorporated
XX *			    Minnesota Supercomputer Center
XX *
XX * Permission is hereby granted to use this software on any computer system
XX * and to copy this software, including for purposes of redistribution, subject
XX * to the conditions that 
XX *
XX *  o  The full text of this copyright message is retained and prominently
XX *      displayed
XX *
XX *  o  No misrepresentation is made as to the authorship of this software
XX *
XX *  o  The software is not used for resale or direct commercial advantage
XX *
XX *  By copying, installing, or using this software, the user agrees to abide
XX *  by the above terms and agrees that the software is accepted on an "as is"
XX *  basis, WITHOUT WARRANTY expressed or implied, and relieves Research Equip-
XX *  ment Inc., its affiliates, officers, agents, and employees of any and all
XX *  liability, direct of consequential, resulting from copying, installing
XX *  or using this software.
XX */
XX#ifndef lint
XXstatic char *copyright = "Copyright (c) 1986, Research Equipment Incorporated.";
XX#endif

XX/*
XX * Make initial program,
XX * Alan Klietz, Nov 11, 1985.
XX */

XX/*
XX * Declare global externals
XX */
XXstruct	fi_file		file;
XXstruct	li_line		*line_array;
XXstruct  ya_yank		yank_array[NUM_YANK_BUFS];
XXstruct	un_undo		undo;
XXstruct	wi_window	window;
XXstruct	sc_screen	screen;

XXINT	errflag;	/* 1 if error in command line parsing */
XXINT	nwin_lines;	/* Number of lines in window */
XXchar    editlist[256];	/* List of files to edit */
XXchar	**Argv;
XXboolean	use_linemode = 1 ;/* TRUE to set linemode on tty during shell escapes */

XX/*
XX * Parse command line arguments
XX * Call major routines
XX */
XXmain(argc, argv)
XXint argc;
XXchar **argv;
XX{
XX	void  rv_cmd(), usage(), initialize();

XX	if (argc < 4)
XX		usage();
XX	Argv = argv;
XX	strncpy(editlist, argv[3], 255);
XX	if (argc == 5)
XX		use_linemode++;
XX	initialize();
XX	rv_cmd();
XX	/*NOTREACHED*/
XX}


XXvoid
XXusage()
XX{
XX	fprintf(stderr, "Usage: rvi in_fd out_fd \"files\"\n");
XX	exit(1);
XX}
@//E*O*F rv_main.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_mark.c
if test -f rv_mark.c ; then
    echo rv_mark.c exists, putting output in $$rv_mark.c
    OUT=$$rv_mark.c
    STATUS=1
else
    OUT=rv_mark.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_mark.c//'
XX#include "rv.h"

XXvoid
XXrv_mark()
XX{
XX	register INT	c;

XX	c = getch();
XX	if (c < 'a' || c > 'z') {
XX		botprint(TRUE, "Mark must be a letter from 'a' to 'z'");
XX		errflag = 1;
XX		return;
XX	}
XX	xmit_curline();
XX	xmit_ed("%dk%c\n", screen.sc_lineno, c);
XX}
@//E*O*F rv_mark.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_print_ln.c
if test -f rv_print_ln.c ; then
    echo rv_print_ln.c exists, putting output in $$rv_print_ln.c
    OUT=$$rv_print_ln.c
    STATUS=1
else
    OUT=rv_print_ln.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_print_ln.c//'
XX#include "rv.h"

XXvoid
XXprint_line(s)
XX/*
XX * Print line to screen at current cursor loc.
XX */
XXchar	*s;
XX{
XX	char	*uchr;

XX	--s;
XX	while(*++s) {
XX		if (*s < ' ' || *s > '~') /* If control char */
XX			if (*s == '\t' && !set_list) /* tab */
XX/* Alan - Expand this using set_tabstops!! */
XX/* Ugh.. later.  This loop is already too slow.  AEK */
XX				addch(*s); 
XX			else {
XX				/*
XX				 * Expand control char to ^x
XX				 */
XX				uchr = unctrl(*s);
XX				addch(uchr[0]);
XX				addch(uchr[1]);
XX			}
XX		else
XX			addch(*s);
XX	}
XX	if (set_list)
XX		addch('$');
XX#ifndef USG
XX	/*
XX	 * KLUDGE - Handle xenl brain damage in the VT100 and
XX	 * Concept 100 until Berkeley cleans up it's Curses implementation
XX	 */
XX	if (XN && CURCOLUMN==0) {
XX		addch(' '); 
XX		refresh();
XX		addch('\b');
XX	}
XX#endif
XX}
@//E*O*F rv_print_ln.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo x - rv_quit.c
if test -f rv_quit.c ; then
    echo rv_quit.c exists, putting output in $$rv_quit.c
    OUT=$$rv_quit.c
    STATUS=1
else
    OUT=rv_quit.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F rv_quit.c//'
XX#include "rv.h"

XXboolean input_mode;
XXINT  set_debug = 0;
XXboolean set_list;
XXboolean set_autoindent = FALSE;
XXboolean set_fortran;
XXINT  set_scroll;
XXINT  set_tabstops = 8;
XX#ifdef CRAY
XXboolean set_timeout = FALSE;
XX#else
XXboolean set_timeout = TRUE;
XX#endif
XXINT  set_shiftwidth = 8;
XXboolean set_wrapscan = TRUE;

XXvoid
XXcleanup()
XX{
XX	char buf[NUM_YANK_BUFS*20+8], *s;
XX	INT i;

XX	xmit_curline();
XX	refresh();

XX	/*
XX	 * Remove all yank buffers
XX	 */
XX	strcpy(buf, "!rm -f");
XX	s = &buf[strlen(buf)];
XX	yank_array[NUM_YANK_BUFS-1].ya_madefile = TRUE;
XX	for (i=0; i < NUM_YANK_BUFS; ++i)
XX		if (yank_array[i].ya_madefile) {
XX			sprintf(s, " /tmp/yk%d.%d", getpid(), i);
XX			s += strlen(s);
XX		}
XX	*s++ = '\n';
XX	*s = '\0';
XX	fputs(buf, file.fi_fpout);
XX}


XXvoid
XXquit()
XX{
XX	cleanup();
XX	xmit_sync();
XX	(void) recv_sync(TRUE);
XX	move(LINES-1,0);
XX	refresh();
XX	endwin();
XX	exit(0);
XX}


XXvoid
XXQuit()
XX{
XX	cleanup();
XX	xmit_sync();
XX	(void) recv_sync(TRUE);
XX	xmit_ed("Q\n");
XX	fflush(file.fi_fpout);
XX	move(LINES-1,0);
XX	refresh();
XX	endwin();
XX	exit(0);
XX}
@//E*O*F rv_quit.c//
chmod u=rw,g=rw,o=rw $OUT
 
echo Inspecting for damage in transit...
temp=/tmp/sharin$$; dtemp=/tmp/sharout$$
trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
cat > $temp <<\!!!
     207    1235    7675 rv.h
     738    1756   13590 rv_cmd.c
     143     406    3637 rv_delete.c
      13      15     102 rv_dummy.c
     128     423    2954 rv_edit.c
     161     434    2827 rv_fast.c
     172     539    3861 rv_fetch.c
      28      56     377 rv_flash.c
     101     230    1451 rv_forback.c
     105     253    1805 rv_getline.c
     218     654    4549 rv_init.c
      49     156     995 rv_input.c
     100     264    1924 rv_join.c
      78     318    2048 rv_main.c
      16      40     241 rv_mark.c
      43     125     751 rv_print_ln.c
      69     121    1005 rv_quit.c
    2369    7025   49792 total
!!!
wc $FILES | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
if test -s $dtemp ; then
    echo "Ouch [diff of wc output]:"
    cat $dtemp
    STATUS=1
elif test $STATUS = 0 ; then
    echo "No problems found."
else
    echo "WARNING -- PROBLEMS WERE FOUND..."
fi
exit $STATUS