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