[alt.sources] BEAV

pvr@wang.com (Peter Reilley) (06/06/91)

	This is the latest release of BEAV.   I am posting it to alt.sources
because I my posting to comp.sources.unix has not been released by the 
moderator.   It has sat in the mill for over 3 months.   I would like
to find an archive for the source.   If someone would like to archive it
and tell me where I would be most appreciative.    If this is not propper
protocol please excuse me, I am reletively new to news.

	This release 1.20 of BEAV (Binary Editor And Viewer),
a full featured binary file editor.	  Just about any operation that 
you could want to do to a binary file is possible with BEAV.   You 
can insert or delete in the middle of a file thereby changing it's size.
You can display and edit data in hex, octal, decimal, binary, ascii, 
or ebcdic formats.   You can display data in byte, word, or long word 
formats in either Intel or Motorola byte ordering.   You can send the 
formatted display mode to a file or printer.

      Version 1.20  (3/10/91)  of  beav  contains  the  following
fixes and enhancements;

*           Under   unix   files   are  created  with  read/write
      permissions.

*           Fixed the  bug  in  the  terminal  I/O  routine  that
      caused  beav  to  spin  rather  than  give  up control when
      waiting for a character.

*           Added the ANSI #define that was missing for MSDOS.

*           Changed the D16 #define to a unsigned short.

*           Called ttclose on error exit.

*           Check and limit ncol and nrow to  the  actual  screen
      array size.

*           Add  the  ability  to  load  key bindings from a file
      automatically under MSDOS and unix.

*           Add delete current window command.

*           Support VT100 type function keys.

	BEAV is based on the source for emacs for display and keyboard handling 
functions.   The binary file handling and display formats are special
to BEAV.   There is a full manual included in this release.   There
are makefiles for unix, xenix 286, and MSC 5.1 under DOS.   The old Wang PC
is supported.   This has been tested on 286 and 386 PC's under SCO UNIX and
XENIX as well as under UNIX on a MIPS system.
	I am willing to maintain BEAV and will entertain suggestions for
modifications and/or bug fixes.   I can be reached at;

		pvr@wang.com

or at;

		Peter Reilley
		19 Heritage Cir.
		Hudson, N.H. 03051

-----> CUT HERE <-----> CUT HERE <-----> CUT HERE <-----> CUT HERE <-----
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 10)."
# Contents:  cinfo.c ebcdic.c editor.lnk fileio.c kbd.c lintfunc.dec
#   machine.c makefile.286 makefile.dos makefile.unx region.c spawn.c
#   tcap.c termio.c tty.c ttyio.c wangpc.c word.c
# Wrapped by pvr@elf on Thu Mar 14 08:16:45 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'cinfo.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cinfo.c'\"
else
echo shar: Extracting \"'cinfo.c'\" \(2700 characters\)
sed "s/^X//" >'cinfo.c' <<'END_OF_FILE'
X/*
X*		Character class tables.
X* Do it yourself character classification
X* macros, that understand the multinational character set,
X* and let me ask some questions the standard macros (in
X* ctype.h) don't let you ask.
X*/
X#define LINT_ARGS   1           /* enable lint type checking */
X#include	"def.h"
X#include	"lintfunc.dec"
X/*
X* This table, indexed by a character drawn
X* from the 256 member character set, is used by my
X* own character type macros to answer questions about the
X* type of a character. It handles the full multinational
X* character set, and lets me ask some questions that the
X* standard "ctype" macros cannot ask.
X*/
Xchar    cinfo[256] =
X{
X
X    _C, _C, _C, _C,             /* 0x0X	 */
X    _C, _C, _C, _C,
X    _C, _C, _C, _C,
X    _C, _C, _C, _C,
X    _C, _C, _C, _C,             /* 0x1X	 */
X    _C, _C, _C, _C,
X    _C, _C, _C, _C,
X    _C, _C, _C, _C,
X    0, 0, 0, 0,                 /* 0x2X	 */
X    _W, 0, 0, _W,
X    0, 0, 0, 0,
X    0, 0, 0, 0,
X    _W, _W, _W, _W,             /* 0x3X	 */
X    _W, _W, _W, _W,
X    _W, _W, 0, 0,
X    0, 0, 0, 0,
X    0, _U | _W, _U | _W, _U | _W,/* 0x4X	 */
X    _U | _W, _U | _W, _U | _W, _U | _W,
X    _U | _W, _U | _W, _U | _W, _U | _W,
X    _U | _W, _U | _W, _U | _W, _U | _W,
X    _U | _W, _U | _W, _U | _W, _U | _W,/* 0x5X	 */
X    _U | _W, _U | _W, _U | _W, _U | _W,
X    _U | _W, _U | _W, _U | _W, 0,
X    0, 0, 0, _W,
X    0, _L | _W, _L | _W, _L | _W,/* 0x6X	 */
X    _L | _W, _L | _W, _L | _W, _L | _W,
X    _L | _W, _L | _W, _L | _W, _L | _W,
X    _L | _W, _L | _W, _L | _W, _L | _W,
X    _L | _W, _L | _W, _L | _W, _L | _W,/* 0x7X	 */
X    _L | _W, _L | _W, _L | _W, _L | _W,
X    _L | _W, _L | _W, _L | _W, 0,
X    0, 0, 0, _C,
X    0, 0, 0, 0,                 /* 0x8X	 */
X    0, 0, 0, 0,
X    0, 0, 0, 0,
X    0, 0, 0, 0,
X    0, 0, 0, 0,                 /* 0x9X	 */
X    0, 0, 0, 0,
X    0, 0, 0, 0,
X    0, 0, 0, 0,
X    0, 0, 0, 0,                 /* 0xAX	 */
X    0, 0, 0, 0,
X    0, 0, 0, 0,
X    0, 0, 0, 0,
X    0, 0, 0, 0,                 /* 0xBX	 */
X    0, 0, 0, 0,
X    0, 0, 0, 0,
X    0, 0, 0, 0,
X    _U | _W, _U | _W, _U | _W, _U | _W,/* 0xCX	 */
X    _U | _W, _U | _W, _U | _W, _U | _W,
X    _U | _W, _U | _W, _U | _W, _U | _W,
X    _U | _W, _U | _W, _U | _W, _U | _W,
X    0, _U | _W, _U | _W, _U | _W,/* 0xDX	 */
X    _U | _W, _U | _W, _U | _W, _U | _W,
X    _U | _W, _U | _W, _U | _W, _U | _W,
X    _U | _W, _U | _W, 0, _W,
X    _L | _W, _L | _W, _L | _W, _L | _W,/* 0xEX	 */
X    _L | _W, _L | _W, _L | _W, _L | _W,
X    _L | _W, _L | _W, _L | _W, _L | _W,
X    _L | _W, _L | _W, _L | _W, _L | _W,
X    0, _L | _W, _L | _W, _L | _W,/* 0xFX	 */
X    _L | _W, _L | _W, _L | _W, _L | _W,
X    _L | _W, _L | _W, _L | _W, _L | _W,
X    _L | _W, _L | _W, 0, 0
X}
X       ;
END_OF_FILE
if test 2700 -ne `wc -c <'cinfo.c'`; then
    echo shar: \"'cinfo.c'\" unpacked with wrong size!
fi
chmod +x 'cinfo.c'
# end of 'cinfo.c'
fi
if test -f 'ebcdic.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ebcdic.c'\"
else
echo shar: Extracting \"'ebcdic.c'\" \(2681 characters\)
sed "s/^X//" >'ebcdic.c' <<'END_OF_FILE'
X
X#define LINT_ARGS   1           /* enable lint type checking */
X#include    "def.h"
X
Xextern    char    ERR_ebcdic[];
X
X#include    "lintfunc.dec"
X/* Function definitions */
X
X/* This table defines the translation from EBCDIC code to ASCII. */
X
Xchar    ebcdic_table[] =
X{0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* 00-07 */
X    0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* 08-0F */
X    0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* 10-17 */
X    0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* 18-1F */
X    0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* 20-27 */
X    0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* 28-2F */
X    0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* 30-37 */
X    0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* 38-3F */
X    0x20, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* 40-47 */
X    0x2E, 0x2E, 0x2E, 0x2E, 0x3C, 0x28, 0x2B, 0x2E,/* 48-4F */
X    0x26, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* 50-57 */
X    0x2E, 0x2E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,/* 58-5F */
X    0x2D, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* 60-67 */
X    0x2E, 0x2E, 0x7C, 0x2E, 0x25, 0x5F, 0x3E, 0x3F,/* 68-6F */
X    0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x27, 0x2E, 0x2E,/* 70-77 */
X    0x2E, 0x60, 0x3A, 0x23, 0x40, 0x2C, 0x3D, 0x22,/* 78-7F */
X    0x2E, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,/* 80-87 */
X    0x68, 0x69, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* 88-8F */
X    0x2E, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,/* 90-97 */
X    0x71, 0x72, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* 98-9F */
X    0x2E, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,/* A0-A7 */
X    0x79, 0x7A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* A8-AF */
X    0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* B0-B7 */
X    0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* B8-BF */
X    0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,/* C0-C7 */
X    0x48, 0x49, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* C8-CF */
X    0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,/* D0-D7 */
X    0x51, 0x52, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* D8-DF */
X    0x5C, 0x2E, 0X53, 0x54, 0x55, 0x56, 0x57, 0x58,/* E0-E7 */
X    0x59, 0x5A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,/* E8-EF */
X    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,/* F0-F7 */
X    0x38, 0x39, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E/* F8-FF */
X};
X
X/* convert a ASCII character to an EBCDIC character */
Xchar    to_ebcdic (ch)
X
Xchar    ch;
X{
X    int     cnt;
X    char    buf[70], buf1[70];
X
X    for (cnt = 0; cnt < sizeof (ebcdic_table); cnt++)
X        {
X        if (ch == ebcdic_table[cnt])
X            return (cnt);
X        }
X    sprintf (buf1, ERR_ebcdic, R_BYTE_FMT(curwp));
X    sprintf (buf, buf1, ch);
X    writ_echo(buf);
X    return (0);
X}
END_OF_FILE
if test 2681 -ne `wc -c <'ebcdic.c'`; then
    echo shar: \"'ebcdic.c'\" unpacked with wrong size!
fi
chmod +x 'ebcdic.c'
# end of 'ebcdic.c'
fi
if test -f 'editor.lnk' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'editor.lnk'\"
else
echo shar: Extracting \"'editor.lnk'\" \(193 characters\)
sed "s/^X//" >'editor.lnk' <<'END_OF_FILE'
XBASIC +BUFFER +CINFO +DISPLAY +ECHO +EXTEND + EBCDIC +
XFILE +FILEIO +FORMAT +KBD +LINE +MAIN +RANDOM +REGION +
XSEARCH +SPAWN +SYMBOL +TEXT +TTY +TTYIO +TTYKBD +
XWINDOW +WORD + WANGPC
XBEAV.EXE;
END_OF_FILE
if test 193 -ne `wc -c <'editor.lnk'`; then
    echo shar: \"'editor.lnk'\" unpacked with wrong size!
fi
chmod +x 'editor.lnk'
# end of 'editor.lnk'
fi
if test -f 'fileio.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fileio.c'\"
else
echo shar: Extracting \"'fileio.c'\" \(4787 characters\)
sed "s/^X//" >'fileio.c' <<'END_OF_FILE'
X/*
X*    file I/O.
X*/
X#include	<sys/types.h> 
X#include        "def.h"
X
X#ifdef UNIX
X#include	<fcntl.h> 
X#include	<sys/stat.h> 
X#endif
X 
Xextern    char    MSG_cnt_wr[];
Xextern    char    MSG_wr_io_er[];
Xextern    char    MSG_rd_er[];
Xextern    char    MSG_bak[];
Xextern    char    MSG_backup[];
Xextern    char    MSG_back_er[];
Xextern    char    MSG_back_of[];
X
X#include    "lintfunc.dec"
X
X#ifdef MSDOS
Xstatic  FILE * ffp;
X#endif
X
X#ifdef UNIX
Xstatic  int ffp;
X#endif
X
X/*
X* Open a file for reading.
X*/
Xchar    ffropen (fn)
Xchar   *fn;
X{
X#ifdef MSDOS
X    if ((ffp = fopen (fn, "rb")) == NULL)/* pvr */
X        return (FIOERR);;
X    return (FIOSUC);
X#endif
X#ifdef UNIX
X    if ((ffp = open (fn, O_RDONLY)) == -1)/* pvr */
X        return (FIOERR);;
X    return (FIOSUC);
X#endif
X}
X/*
X*   Get the file length
X*/
XA32 file_len ()
X    {
X#ifdef MSDOS
X    return (filelength (fileno (ffp)));
X#endif
X#ifdef UNIX
X	struct	stat	st;
X	
X	if (fstat (ffp, &st) == -1)
X		return (-1);
X	return (st.st_size);
X#endif
X    }
X
X/*
X* Open a file for writing.
X* Return TRUE if all is well, and
X* FALSE on error (cannot create).
X*/
Xchar    ffwopen (fn)
Xchar   *fn;
X{
X#ifdef MSDOS
X    if ((ffp = fopen (fn, "wb")) == NULL)/* pvr */
X        {
X        writ_echo (MSG_cnt_wr);
X        return (FIOERR);
X        }
X    return (FIOSUC);
X#endif
X#ifdef UNIX
X	/* set perms  1.13 */
X    if ((ffp = open (fn, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE)) == -1)/* pvr */
X        return (FIOERR);;
X    return (FIOSUC);
X#endif
X}
X
X/*
X* Close a file.
X* Should look at the status.
X*/
Xchar    ffclose ()
X{
X#ifdef MSDOS
X    fclose (ffp);
X#endif
X#ifdef UNIX
X    close (ffp);
X#endif
X    return (FIOSUC);
X}
X
X/*
X* Write a line to the already
X* opened file. The "buf" points to the
X* buffer, and the "nbuf" is its length.   pvr
X* Return the status.
X*/
Xchar    ffputline (buf, nbuf)
Xregister char   buf[];
Xint     nbuf;
X{
X    register int    i;
X
X#ifdef MSDOS
X    i = fwrite (buf, 1, nbuf, ffp);
X#endif
X#ifdef UNIX 
X    i = write (ffp, buf, nbuf);
X#endif
X
X    if ((i != nbuf)
X#ifdef MSDOS	
X 		|| (ferror (ffp) != FALSE))
X#else
X		)
X#endif     
X	    {
X        writ_echo (MSG_wr_io_er);
X        return (FIOERR);
X        }
X    return (FIOSUC);
X}
X
X/*
X* Read a line from a file, and store the bytes
X* in the supplied buffer. Stop on end of file or after 'nbuf' characters. pvr
X* the first byte in the buffer is the length in bytes.
X*/
Xchar    ffgetline (buf, nbuf, rbuf)
Xregister char   *buf;
Xregister int    *rbuf, nbuf;
X{
X
X    register int    c;
X    register int    i;
X
X#ifdef MSDOS
X    *rbuf = fread (buf, 1, nbuf, ffp); 
X#endif
X
X#ifdef UNIX
X    *rbuf = read (ffp, buf, nbuf); 
X#endif
X
X    /* End of file.         */
X#ifdef MSDOS
X    if (ferror (ffp) != FALSE)
X        {
X        writ_echo (MSG_rd_er);
X        return (FIOERR);
X        }
X#endif
X    if (*rbuf == 0)
X        return (FIOEOF);
X
X    return (FIOSUC);
X}
X
X/*
X*   Seek to specified position in file.
X*   Return the actual position in the file.
X*/
XA32     ffseek (posn)
X    A32     posn;
X    {
X#ifdef MSDOS
X    fseek (ffp, posn, SEEK_SET);
X    return (ftell (ffp));
X#endif
X#ifdef UNIX
X	return (lseek (ffp, posn, 0));
X#endif
X    }
X
X/*
X* Some backup user on MS-DOS might want
X* to determine some rule for doing backups on that
X* system, and fix this. I don't use MS-DOS, so I don't
X* know what the right rules would be. Return TRUE so
X* the caller does not abort a write.
X*/
X#if BACKUP
Xbool    fbackupfile (fname)
Xchar   *fname;
X{
X    FILE * backupfile;
X    char    backname[128];
X    char   *source,
X           *backup;
X    extern char time_string[];
X    char    buf[80];
X
X    source = fname;
X    backup = backname;
X    while ((*source > 0) && (*source != '.'))
X        {
X        *backup = *source;
X        backup++;
X        source++;
X        *backup = 0;
X        }
X    strcat (backname, MSG_bak);
X    sprintf (buf, MSG_backup, fname, backname);
X    writ_echo (buf);
X    unlink (backname);
X#ifdef MSDOS
X    if (rename (backname, fname) > 0)
X#else
X    if ((link (fname, backname) != 0) || (unlink (fname) != 0))
X#endif
X        {
X        sprintf (buf, MSG_back_er, fname, backname);
X        writ_echo (buf);
X        return (FALSE);
X        }
X    return (TRUE);              /* Hack.                */
X}
X
X#endif
X
X/*
X* The string "fn" is a file name.
X* Perform any required case adjustments. All systems
X* we deal with so far have case insensitive file systems.
X* We zap everything to lower case. The problem we are trying
X* to solve is getting 2 buffers holding the same file if
X* you visit one of them with the "caps lock" key down.
X* On UNIX file names are dual case, so we leave
X* everything alone.
X*/
Xvoid    adjustcase (fn)
Xregister char  *fn;
X{
X    register int    c;
X
X    while ((c = *fn) != 0)
X        {
X        if (c >= 'A' && c <= 'Z')
X            *fn = c + 'a' - 'A';
X        ++fn;
X        }
X}
X
X
END_OF_FILE
if test 4787 -ne `wc -c <'fileio.c'`; then
    echo shar: \"'fileio.c'\" unpacked with wrong size!
fi
chmod +x 'fileio.c'
# end of 'fileio.c'
fi
if test -f 'kbd.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kbd.c'\"
else
echo shar: Extracting \"'kbd.c'\" \(4640 characters\)
sed "s/^X//" >'kbd.c' <<'END_OF_FILE'
X/*                      KBD.C
X*       Terminal independent keyboard handling.
X*/
X#define LINT_ARGS   1           /* enable lint type checking */
X#include    "def.h"
X
Xchar    *keystrings ();
X
Xextern    char    MSG_tab[];
Xextern    char    MSG_esc[];
Xextern    char    MSG_ctl_x[];
Xextern    char    MSG_ctl[];
Xextern    char    MSG_fn[];
Xextern    char    MSG_ret[];
Xextern    char    MSG_bksp[];
Xextern    char    MSG_space[];
Xextern    char    MSG_rubout[];
X
X#include    "lintfunc.dec"
X/*
X* Read in a key, doing the terminal
X* independent prefix handling. The terminal specific
X* "getkbd" routine gets the first swing, and may return
X* one of the special codes used by the special keys
X* on the keyboard. The "getkbd" routine returns the
X* C0 controls as received; this routine moves them to
X* the right spot in 11 bit code.
X*/
Xint     getkey ()
X{
X
X    register int    c;
X    c = getkbd ();
X    if (c == METACH)            /* M-           */
X	{
X        c = KMETA | getctl ();
X#ifdef VT100KEY
X		if ((c & KCHAR) == '[')
X			c = KMETA | KCTRL | KCTLX | getctl ();	/* flag VT100 sequence */
X#endif
X	}
X    else if (c == CTRLCH)        /* C-           */
X        c = KCTRL | getctl ();
X    else if (c == CTMECH)    /* C-M-         */
X        c = KCTRL | KMETA | getctl ();
X    else if (c >= 0x00 && c <= 0x1F)/* Relocate control.    */
X        c = KCTRL | (c + '@');
X
X    if (c == (KCTRL | 'X'))     /* C-X          */
X        c = KCTLX | getctl ();
X    return (c);
X}
X
X
X/*
X* Used above.
X*/
Xint     getctl ()
X{
X
X    register int    c;
X
X#if 1
X    c = getkbd ();
X    if (c == METACH)            /* M-           */
X        c = KMETA | getctl ();
X    else
X        if (c == CTRLCH)        /* C-           */
X            c = KCTRL | getctl ();
X    else
X        if (c == CTMECH)    /* C-M-         */
X            c = KCTRL | KMETA | getctl ();
X     else
X        if (c >= 0x00 && c <= 0x1F)/* Relocate control.    */
X            c = KCTRL | (c + '@');
X#else
X    c = getkey ();              /* Note recursion   */
X    if (ISLOWER (c & 0xFF))
X        c = (c & ~0xFF) | TOUPPER (c & 0xFF);
X    if (c >= 0x00 && c <= 0x1F) /* Relocate control.    */
X        c = KCTRL | (c + '@');
X#endif
X    if (ISLOWER (c & 0xFF))
X        c = (c & ~0xFF) | TOUPPER (c & 0xFF);
X    return (c);
X}
X
X
X/*
X* Transform a key code into a name,
X* using a table for the special keys and combination
X* of some hard code and some general processing for
X* the rest. None of this code is terminal specific any
X* more. This makes adding keys easier.
X*/
Xvoid keyname (cp, k)
Xregister char  *cp;
Xregister int    k;
X{
X    register char  *np;
X    char    nbuf[3];
X
X    static char hex[] =
X    {
X        '0', '1', '2', '3',
X        '4', '5', '6', '7',
X        '8', '9', 'A', 'B',
X        'C', 'D', 'E', 'F'
X    };
X	*cp = 0;	/* terminate previous string */
X#ifdef VT100KEY
X	if ((k & (KMETA | KCTRL | KCTLX)) == (int)(KMETA | KCTRL | KCTLX)) 
X		{
X        sprintf (&cp[strlen (cp)], MSG_fn);
X        sprintf (&cp[strlen (cp)], "%c", k & KCHAR);
X		return;
X		}
X#endif
X    if (k & 0x80)
X        {
X        if ((np = keystrings (k)) != NULL)
X            {
X            if ((k & KMETA) != 0)
X		        sprintf (&cp[strlen (cp)], MSG_esc);
X
X            strcat (cp, np);
X            }
X        else
X			cp[strlen (cp)] = 0;    /* null string */
X        return;
X        }
X
X    if ((k & KCTLX) != 0)
X        {
X        /* Ctl-X prefix.      */
X        sprintf (&cp[strlen (cp)], MSG_ctl_x);
X        k &= ~KCTLX;
X        }
X
X    if ((k & KMETA) != 0)
X        {
X        /* Add Esc- mark.     */
X        sprintf (&cp[strlen (cp)], MSG_esc);
X        k &= ~KMETA;
X        }
X
X    if (k == (KCTRL | 'I'))/* Some specials.   */
X        np = MSG_tab;
X    else
X        {
X        if (k == (KCTRL | 'M'))
X            np = MSG_ret;
X        else if (k == (KCTRL | 'H'))
X            np = MSG_bksp;
X        else if (k == ' ')
X            np = MSG_space;
X        else if (k == 0x7F)
X            np = MSG_rubout;
X        else
X            {
X            if ((k & KCTRL) != 0)
X                {
X                /* Add Ctl- mark.     */
X		        sprintf (&cp[strlen (cp)], MSG_ctl);
X                }
X            np = &nbuf[0];
X            if (((k & KCHAR) >= 0x20 && (k & KCHAR) <= 0x7E)
X                 || ((k & KCHAR) >= 0xA0 && (k & KCHAR) <= 0xFE))
X                {
X                nbuf[0] = k & KCHAR;/* Graphic.     */
X                nbuf[1] = 0;
X                }
X            else
X                {
X                /* Non graphic.     */
X                nbuf[0] = hex[(k >> 4) & 0x0F];
X                nbuf[1] = hex[k & 0x0F];
X                nbuf[2] = 0;
X                }
X            }
X        }
X    strcat (cp, np);
X}
X
END_OF_FILE
if test 4640 -ne `wc -c <'kbd.c'`; then
    echo shar: \"'kbd.c'\" unpacked with wrong size!
fi
chmod +x 'kbd.c'
# end of 'kbd.c'
fi
if test -f 'lintfunc.dec' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lintfunc.dec'\"
else
echo shar: Extracting \"'lintfunc.dec'\" \(25 characters\)
sed "s/^X//" >'lintfunc.dec' <<'END_OF_FILE'
X/* Dummy include file */
END_OF_FILE
if test 25 -ne `wc -c <'lintfunc.dec'`; then
    echo shar: \"'lintfunc.dec'\" unpacked with wrong size!
fi
# end of 'lintfunc.dec'
fi
if test -f 'machine.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'machine.c'\"
else
echo shar: Extracting \"'machine.c'\" \(2190 characters\)
sed "s/^X//" >'machine.c' <<'END_OF_FILE'
X/* This program sniffs around to see what type of MSDOS computer
X    it is running in
X*/
X
X/* Checks what type of machine it is running in and returns
X        0 if unknown
X        1 if Wang PC
X        2 if Wang APC
X        3 if IBM PC/XT
X        4 if IBM PC/AT
X        5 if IBM PC Jr
X        6 if IBM PC
X        7 if Wang Laptop
X	8 if Wang PC200
X        9 if Wang PC300
X       10 if IBM PS/2
X*/
Xint host_mach()
X{
Xunsigned char far *memptr;
Xunsigned char    c;
Xint i, match;
Xstatic char wang_pc[]={"WANG PROFE"};
Xstatic char wang_apc[]={"WANG ADVAN"};
Xstatic char wang_lap[]={"WANG"};
X
X/* test for Wang PC */
Xmemptr = (unsigned char far *)0xFC003FC2L;
Xmatch = 1;
Xfor (i=0;(i<10 && match!=0);i++)
X    {
X    if(*memptr != wang_pc[i])
X        match=0;
X    memptr++;
X    }
Xif(match ==1)
X    return(1);
X
X/* test for Wang APC */
Xmemptr = (unsigned char far *)0xFC003FC2L;
Xmatch = 1;
Xfor (i=0;(i<10 && match!=0);i++)
X    {
X    if(*memptr != wang_apc[i])
X	match=0;
X    memptr++;
X    }
Xif(match ==1)
X    return(2);
X
X/* test for Wang Laptop */
Xmemptr = (unsigned char far *)0xFC003FC2L;
Xmatch = 1;
Xfor (i=0;(i<4 && match!=0);i++)
X    {
X    if(*memptr != wang_pc[i])
X	match=0;
X    memptr++;
X    }
Xif(match ==1)
X    /* I should really do an INT 88h func 0 now to verify for sure
X       but I'm too lazy!
X    */
X    return(7);
X
X/* Must be an IBM or clone */
Xmemptr = (unsigned char far *)0xF000FFFEL;
Xc = *memptr;
X
Xswitch(c)
X    {
Xcase 0xFC:  /* IBM AT or clone */
X	    /* for the moment a PC200 is the same as an AT */
X            return(4);
X
Xcase 0xFD:  /* IBM PC Jr */
X            return(5);
X
Xcase 0xFE:  /* IBM XT or clone */
X            return(3);
X
Xcase 0xFF:  /* IBM PC or clone */
X            return(6);
X
X    }
X
Xreturn(0);
X}
X
X
X
Xmain()
X{
Xint machine;
X
Xmachine = host_mach();
X
Xprintf("This is a ");
Xswitch(machine)
X      {
Xcase 0: printf("unknown type of machine\n");
X        break;
Xcase 1: printf("Wang PC\n");
X        break;
Xcase 2: printf("Wang Advanced PC\n");
X        break;
Xcase 3: printf("IBM PC/XT\n");
X        break;
Xcase 4: printf("IBM PC/AT\n");
X        break;
Xcase 5: printf("IBM PC Jr\n");
X	break;
Xcase 6: printf("IBM PC \n");
X	break;
Xcase 7: printf("Wang LapTop\n");
X	break;
X      }
X
X}
END_OF_FILE
if test 2190 -ne `wc -c <'machine.c'`; then
    echo shar: \"'machine.c'\" unpacked with wrong size!
fi
chmod +x 'machine.c'
# end of 'machine.c'
fi
if test -f 'makefile.286' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile.286'\"
else
echo shar: Extracting \"'makefile.286'\" \(655 characters\)
sed "s/^X//" >'makefile.286' <<'END_OF_FILE'
X# This is a makefile for 286 xenix
XCFLAGS=     -O -Ml -DUNIX
X
XOFILES=		basic.o ebcdic.o fileio.o region.o text.o wangpc.o \
X	buffer.o echo.o main.o search.o tty.o window.o \
X	cinfo.o extend.o kbd.o spawn.o ttyio.o termio.o tcap.o word.o \
X	display.o file.o line.o random.o symbol.o ttykbd.o format.o
X
X
XCFILES=     basic.c ebcdic.c fileio.c region.c text.c wangpc.c \
X	buffer.c echo.c format.c main.c search.c tty.c window.c \
X	cinfo.c extend.c kbd.c spawn.c ttyio.c termio.c tcap.c word.c \
X	display.c file.c line.c random.c symbol.c ttykbd.c
X
XHFILES=     def.h
X
Xbeav:     $(OFILES)
X	$(CC) $(CFLAGS) $(OFILES) -ltermcap -lc -o beav
X
X(OFILES):  $(HFILES)
X
END_OF_FILE
if test 655 -ne `wc -c <'makefile.286'`; then
    echo shar: \"'makefile.286'\" unpacked with wrong size!
fi
# end of 'makefile.286'
fi
if test -f 'makefile.dos' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile.dos'\"
else
echo shar: Extracting \"'makefile.dos'\" \(1914 characters\)
sed "s/^X//" >'makefile.dos' <<'END_OF_FILE'
X# make BEAV  MSC 5.1
X
XBASIC.OBJ: BASIC.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml BASIC.C ;
X
XBUFFER.OBJ: BUFFER.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml BUFFER.C ;
X
XCINFO.OBJ: CINFO.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml CINFO.C ;
X
XDISPLAY.OBJ: DISPLAY.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml DISPLAY.C ;
X
XEBCDIC.OBJ: EBCDIC.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml EBCDIC.C ;
X
XECHO.OBJ: ECHO.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml ECHO.C ;
X
XEXTEND.OBJ: EXTEND.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml EXTEND.C ;
X
XFILE.OBJ: FILE.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml FILE.C ;
X
XFILEIO.OBJ: FILEIO.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml FILEIO.C ;
X
XFORMAT.OBJ: FORMAT.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml FORMAT.C ;
X
XKBD.OBJ: KBD.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml KBD.C ;
X
XLINE.OBJ: LINE.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml LINE.C ;
X
XMAIN.OBJ: MAIN.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml MAIN.C ;
X
XRANDOM.OBJ: RANDOM.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml RANDOM.C ;
X
XREGION.OBJ: REGION.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml REGION.C ;
X
XSEARCH.OBJ: SEARCH.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml SEARCH.C ;
X
XSPAWN.OBJ: SPAWN.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml SPAWN.C ;
X
XSYMBOL.OBJ: SYMBOL.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml SYMBOL.C ;
X
XTEXT.OBJ: TEXT.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml TEXT.C ;
X
XTTY.OBJ: TTY.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml TTY.C ;
X
XTTYIO.OBJ: TTYIO.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml TTYIO.C ;
X
XTTYKBD.OBJ: TTYKBD.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml TTYKBD.C ;
X
XWANGPC.OBJ: WANGPC.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml WANGPC.C ;
X
XWINDOW.OBJ: WINDOW.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml WINDOW.C ;
X
XWORD.OBJ: WORD.C DEF.H  LINTFUNC.DEC
X CL -c  -Ml WORD.C ;
X
XBEAV.EXE: BASIC.OBJ BUFFER.OBJ CINFO.OBJ DISPLAY.OBJ ECHO.OBJ EXTEND.OBJ \
X        EBCDIC.OBJ FILE.OBJ FILEIO.OBJ FORMAT.OBJ KBD.OBJ LINE.OBJ \
X        MAIN.OBJ RANDOM.OBJ TEXT.OBJ \
X        REGION.OBJ SEARCH.OBJ SPAWN.OBJ SYMBOL.OBJ TTY.OBJ TTYIO.OBJ   \
X        TTYKBD.OBJ WINDOW.OBJ WORD.OBJ WANGPC.OBJ
X LINK   @editor.lnk
X
X
X
X
END_OF_FILE
if test 1914 -ne `wc -c <'makefile.dos'`; then
    echo shar: \"'makefile.dos'\" unpacked with wrong size!
fi
# end of 'makefile.dos'
fi
if test -f 'makefile.unx' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile.unx'\"
else
echo shar: Extracting \"'makefile.unx'\" \(615 characters\)
sed "s/^X//" >'makefile.unx' <<'END_OF_FILE'
XCFLAGS=     -O -DUNIX
X
XOFILES=		basic.o ebcdic.o fileio.o region.o text.o wangpc.o \
X	buffer.o echo.o main.o search.o tty.o window.o \
X	cinfo.o extend.o kbd.o spawn.o ttyio.o termio.o tcap.o word.o \
X	display.o file.o line.o random.o symbol.o ttykbd.o format.o
X
X
XCFILES=     basic.c ebcdic.c fileio.c region.c text.c wangpc.c \
X	buffer.c echo.c format.c main.c search.c tty.c window.c \
X	cinfo.c extend.c kbd.c spawn.c ttyio.c termio.c tcap.c word.c \
X	display.c file.c line.c random.c symbol.c ttykbd.c
X
XHFILES=     def.h
X
Xbeav:     $(OFILES)
X	$(CC) $(CFLAGS) $(OFILES) -ltermcap -lc -o beav
X
X(OFILES):  $(HFILES)
END_OF_FILE
if test 615 -ne `wc -c <'makefile.unx'`; then
    echo shar: \"'makefile.unx'\" unpacked with wrong size!
fi
# end of 'makefile.unx'
fi
if test -f 'region.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'region.c'\"
else
echo shar: Extracting \"'region.c'\" \(4582 characters\)
sed "s/^X//" >'region.c' <<'END_OF_FILE'
X/*
X*       Region based commands.
X* The routines in this file
X* deal with the region, that magic space
X* between "." and mark. Some functions are
X* commands. Some functions are just for
X* internal use.
X*/
X#include    "def.h"
X
Xbool setsize ();
Xbool getregion ();
X
X
Xextern    char    MSG_reg_lrg[];
Xextern    char    MSG_sv_in_b[];
Xextern    char    MSG_sav_slf[];
Xextern    char    MSG_no_mark[];
X
X#include    "lintfunc.dec"
X/*
X* Kill the region. Ask "getregion"
X* to figure out the bounds of the region.
X* Move "." to the start, and kill the characters.
X*/
Xchar    killregion (f, n, k)
X{
X    register char   s;
X    REGION region;
X    int     error;
X
X    if ((s = getregion (&region)) != TRUE)
X        return (s);
X    if ((lastflag & CFKILL) == 0)/* This is a kill type  */
X        kdelete ();             /* clean out k-buffer   */
X    thisflag |= CFKILL;         /* kill buffer stuff.   */
X    curwp -> w_dotp = region.r_linep;
X    curwp -> w_doto = region.r_offset;
X    error = ldelete (region.r_size, TRUE);
X    writ_echo (okmsg);
X    return (error);
X}
X
X
X/*
X* Copy all of the characters in the
X* region to the kill buffer. Don't move dot
X* at all. This is a bit like a kill region followed
X* by a yank.
X*/
Xchar    copyregion (f, n, k)
X{
X    register    LINE * linep;
X    register int    loffs;
X    register char   s;
X    REGION region;
X
X    if ((s = getregion (&region)) != TRUE)
X        return (s);
X    if ((lastflag & CFKILL) == 0)/* Kill type command.   */
X        kdelete ();
X    thisflag |= CFKILL;
X    linep = region.r_linep;     /* Current line.    */
X    loffs = region.r_offset;    /* Current offset.  */
X    while (region.r_size--)
X        {
X        if (loffs == llength (linep))
X            {
X        /* End of line.     */
X            if ((s = kinsert ('\n')) != TRUE)
X                return (s);
X            linep = lforw (linep);
X            loffs = 0;
X            }
X        else
X            {
X        /* Middle of line.  */
X            if ((s = kinsert (lgetc (linep, loffs))) != TRUE)
X                return (s);
X            ++loffs;
X            }
X        }
X    writ_echo (okmsg);
X    return (TRUE);
X}
X
X/*
X* This routine figures out the bound of the region
X* in the current window, and stores the results into the fields
X* of the REGION structure. Dot and mark are usually close together,
X* but I don't know the order. The size is kept in a long. At the
X* end, after the size is figured out, it is assigned to the size
X* field of the region structure. If this assignment loses any bits,
X* then we print an error. This is "type independent" overflow
X* checking. All of the callers of this routine should be ready to
X* get an ABORT status, because I might add a "if regions is big,
X* ask before clobberring" flag.
X*/
Xbool getregion (rp)
Xregister    REGION * rp;
X{
X    if (curwp -> w_markp == NULL)
X        {
X        writ_echo (MSG_no_mark);
X        return (FALSE);
X        }
X
X    if (DOT_POS(curwp) < MARK_POS(curwp))
X        {
X        rp -> r_linep = curwp -> w_dotp;
X        rp -> r_offset = curwp -> w_doto;
X        rp -> r_size = (int)(MARK_POS(curwp) - DOT_POS(curwp));
X        }
X    else
X        {
X        rp -> r_linep = curwp -> w_markp;
X        rp -> r_offset = curwp -> w_marko;
X        rp -> r_size = (int)(DOT_POS(curwp) - MARK_POS(curwp));
X        }
X    return (TRUE);
X}
X
X/*
X* Set size, and check for overflow.
X*/
Xbool setsize (rp, size)
Xregister    REGION * rp;
Xregister long   size;
X{
X    rp -> r_size = size;
X    if (rp -> r_size != size)
X        {
X        writ_echo (MSG_reg_lrg);
X        return (FALSE);
X        }
X    return (TRUE);
X}
X
X
X/* save some region in a buffer
X* (use _usebuffer to handle non-existent buffers)
X* 
X* hack as it uses kill buffer to transfer stuff (quick and dirty!)
X* and doesn't do clever things at all with dot in destination buffer!
X*/
Xchar    save_region (f, n, k)
X{
X    char    bufn[NBUFN];
X    char    oldbufn[NBUFN];
X    register char   s;
X
X    if ((s = ereply (MSG_sv_in_b, bufn, NBUFN, NULL)) != TRUE)
X        return (s);
X
X    if (strcmp (bufn, curbp -> b_bname) == 0)
X        {
X        writ_echo (MSG_sav_slf);
X        return (FALSE);
X        }
X
X /* save this name for ughly reversal */
X    strcpy (oldbufn, curbp -> b_bname);
X
X /* copy stuff using killbuffer as work space -  hack !! * than move it to
X    named place using yank - Quick AND Dirty */
X    copyregion (f, n, k);
X    _usebuffer (bufn);
X    curbp -> b_flag |= BFSAV;   /* mark as a saved buffer */
X
X    yank (f, n, k);
X    kdelete ();                 /* clean out kill buffer */
X    _usebuffer (oldbufn);
X    writ_echo (okmsg);
X    return (TRUE);
X}
X
X
END_OF_FILE
if test 4582 -ne `wc -c <'region.c'`; then
    echo shar: \"'region.c'\" unpacked with wrong size!
fi
chmod +x 'region.c'
# end of 'region.c'
fi
if test -f 'spawn.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'spawn.c'\"
else
echo shar: Extracting \"'spawn.c'\" \(1534 characters\)
sed "s/^X//" >'spawn.c' <<'END_OF_FILE'
X/*
X*    MS-DOS spawn command.com
X*/
X#include        "def.h"
X
Xextern    char    MSG_shell[];
Xextern    char    MSG_def_shell[];
Xextern    char    MSG_pmpt[];
Xextern    char    MSG_pt[];
Xextern    char    MSG_pme[];
Xextern    char    MSG_null[];
X
X#include    "lintfunc.dec"
X/* #include     <dos.h> */
X#if MSDOS
X#include        "process.h"
X#endif
Xchar   *cspec = NULL;           /* Command string.      */
Xchar   *pspec = NULL;
X
X/*
X* Create a subjob with a copy
X* of the command intrepreter in it. When the
X* command interpreter exits, mark the screen as
X* garbage so that you do a full repaint.
X*/
Xbool spawncli (f, n, k)
X{
X#if MSDOS
X
X    char   *getenv ();
X    char    old_prompt[128];
X    char    prompt_line[128];
X
X    ttcolor (CTEXT);            /* Normal color.        */
X    ttmove (nrow - 1, 0);       /* Last line.           */
X    ttflush ();
X    ttcooked ();
X#ifndef IBM
X    strcpy (prompt_line, MSG_pmpt);
X    pspec = getenv (MSG_pt);
X    strcpy (old_prompt, pspec);
X    strcat (prompt_line, pspec);
X    if (strlen (prompt_line - strlen (MSG_pme)) >= 64)
X    /* VERY rude, but setenv not found */
X        {
X        if (putenv (MSG_pmpt) == -1)
X            exit (1);
X        }
X    else
X        if (putenv (prompt_line) == -1)
X            exit (1);
X
X#endif
X    if (!cspec && !(cspec = getenv (MSG_shell)))/* jam */
X        cspec = MSG_def_shell;
X    spawnl (P_WAIT, cspec, MSG_null, NULL);
X    putenv (MSG_pme);
X    if (putenv (old_prompt) == -1)
X        exit (1);
X    ttraw ();
X    sgarbf = TRUE;
X#endif
X    return (TRUE);
X}
X
END_OF_FILE
if test 1534 -ne `wc -c <'spawn.c'`; then
    echo shar: \"'spawn.c'\" unpacked with wrong size!
fi
chmod +x 'spawn.c'
# end of 'spawn.c'
fi
if test -f 'tcap.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tcap.c'\"
else
echo shar: Extracting \"'tcap.c'\" \(2764 characters\)
sed "s/^X//" >'tcap.c' <<'END_OF_FILE'
X/*	tcap:	Unix V5, V7 and BS4.2 Termcap video driver
X		for beav
X*/
X
X#include "def.h"
X
X#ifdef UNIX
X
X#define	MARGIN	8
X#define	SCRSIZ	64
X#define	NPAUSE	10			/* # times thru update to pause */
X#define BEL     0x07
X#define ESC     0x1B
X
Xextern int      ttgetc();
Xextern int      ttputc();
Xextern int		tgetnum();
Xextern int      ttflush();
Xextern int      ttclose();
Xextern int      tput();
Xextern char     *tgoto();
X#if	COLOR
Xextern int		tcapfcol();
Xextern int		tcapbcol();
X#endif
X
X#define TCAPSLEN 315
Xchar tcapbuf[TCAPSLEN];
Xchar *UP, PC, *CM, *CE, *CL, *SO, *SE;
X
Xtcapopen()
X{
X        char *getenv();
X        char *t, *p, *tgetstr();
X        char tcbuf[1024];
X        char *tv_stype;
X        char err_str[72];
X
X        if ((tv_stype = getenv("TERM")) == NULL)
X        {
X                puts("Environment variable TERM not defined!\r");
X 				ttclose();
X                exit(1);
X        }
X
X        if ((tgetent(tcbuf, tv_stype)) != 1)
X        {
X                sprintf(err_str, "Unknown terminal type %s!\r", tv_stype);
X                puts(err_str);
X 				ttclose();	/* fix in 1.13 */
X                exit(1);
X        }
X
X 
X       if ((nrow=(short)tgetnum("li")-1) == -1){
X               puts("termcap entry incomplete (lines)\r");
X    		   ttclose();	/* fix in 1.13 */
X               exit(1);
X       }
X		/* don't allow to specify a larger number of rows than we can handle 1.13 */
X		if (nrow > NROW)
X			nrow = NROW;
X
X       if ((ncol=(short)tgetnum("co")) == -1){
X               puts("Termcap entry incomplete (columns)\r");
X 			   ttclose();	/* fix in 1.13 */
X               exit(1);
X       }
X		/* don't allow to specify a larger number of cols than we can handle 1.13 */
X		if (ncol > NCOL)
X			ncol = NCOL;
X
X    p = tcapbuf;
X    t = tgetstr("pc", &p);
X    if(t)
X        PC = *t;
X
X    CL = tgetstr("cl", &p);
X    CM = tgetstr("cm", &p);
X    CE = tgetstr("ce", &p);
X    UP = tgetstr("up", &p);
X	SE = tgetstr("se", &p);
X	SO = tgetstr("so", &p);
X
X    if(CL == NULL || CM == NULL || UP == NULL)
X        {
X        puts("Incomplete termcap entry\r");
X		ttclose();	/* fix in 1.13 */
X        exit(1);
X        }
X
X    if (p >= &tcapbuf[TCAPSLEN])
X        {
X        puts("Terminal description too big!\r");
X		ttclose();	/* fix in 1.13 */
X        exit(1);
X        }
X}
X
Xtcapmove(row, col)
Xregister int row, col;
X{
X        putpad(tgoto(CM, col, row));
X}
X
Xtcapeeol()
X{
X        putpad(CE);
X}
X
Xtcapeeop()
X{
X        putpad(CL);
X}
X
Xtcaprev(state)		/* change reverse video status */
Xint state;		/* FALSE = normal video, TRUE = reverse video */
X
X{
X	static int revstate = FALSE;
X	if (state) {
X		if (SO != NULL)
X			putpad(SO);
X	} else
X		if (SE != NULL)
X			putpad(SE);
X}
X
Xputpad(str)
Xchar    *str;
X{
X	tputs(str, 1, ttputc);
X}
X
Xputnpad(str, n)
Xchar    *str;
X{
X	tputs(str, n, ttputc);
X}
X
X#endif
END_OF_FILE
if test 2764 -ne `wc -c <'tcap.c'`; then
    echo shar: \"'tcap.c'\" unpacked with wrong size!
fi
# end of 'tcap.c'
fi
if test -f 'termio.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'termio.c'\"
else
echo shar: Extracting \"'termio.c'\" \(3581 characters\)
sed "s/^X//" >'termio.c' <<'END_OF_FILE'
X/*
X * The functions in this file negotiate with the operating system for
X * characters, and write characters in a barely buffered fashion on the display.
X * All operating systems.
X */
X
X#include	<sys/types.h>    /* 1.13 */
X#include    "def.h"
X
X#ifdef UNIX    /* System V */
X
X#include    <stdio.h>
X#include    <signal.h>
X#include    <termio.h>
X#include    <errno.h>
X#include    <fcntl.h>
Xint kbdflgs;            /* saved keyboard fd flags  */
Xint kbdpoll;            /* in O_NDELAY mode         */
Xint kbdqp;          /* there is a char in kbdq  */
Xchar kbdq;          /* char we've already read  */
Xstruct  termio  otermio;    /* original terminal characteristics */
Xstruct  termio  ntermio;    /* charactoristics to use inside */
X
Xextern	errno;		/* System error number -- Necessary when compiling in BSD 1.13 */
X
Xint     nrow;                   /* Terminal size, rows.         */
Xint     ncol;                   /* Terminal size, columns.      */
X
X/*
X * This function is called once to set up the terminal device streams.
X * On VMS, it translates TT until it finds the terminal, then assigns
X * a channel to it and sets it raw. On CPM it is a no-op.
X */
Xttopen()
X{
X    ioctl(0, TCGETA, &otermio); /* save old settings */
X    ntermio.c_iflag = 0;        /* setup new settings */
X    ntermio.c_oflag = 0;
X    ntermio.c_cflag = otermio.c_cflag;
X    ntermio.c_lflag = 0;
X    ntermio.c_line = otermio.c_line;
X    ntermio.c_cc[VMIN] = 1;
X    ntermio.c_cc[VTIME] = 0;
X    ioctl(0, TCSETAW, &ntermio); /* and activate them */
X    kbdflgs = fcntl( 0, F_GETFL, 0 );
X    kbdpoll = FALSE;
X    /* on all screens we are not sure of the initial position
X       of the cursor                    */
X    ttrow = 999;
X    ttcol = 999;
X    nrow = NROW;
X    ncol = NCOL;
X}
X
X/*
X * This function gets called just before we go back home to the command
X * interpreter. On VMS it puts the terminal back in a reasonable state.
X * Another no-operation on CPM.
X */
Xttclose()
X{
X    if (ioctl(0, TCSETAW, &otermio) == -1) /* restore terminal settings */
X		printf ("closing ioctl on dev 0 failure, error = %d\n", errno);
X    if (fcntl(0, F_SETFL, kbdflgs) == -1)
X		printf ("closing fcntl on dev 0 failure, error = %d\n", errno);
X}
X
X/*
X * Write a character to the display. On VMS, terminal output is buffered, and
X * we just put the characters in the big array, after checking for overflow.
X * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
X * MS-DOS (use the very very raw console output routine).
X */
Xttputc(c)
X{
X    fputc(c, stdout);
X}
X
X/*
X * Flush terminal buffer. Does real work where the terminal output is buffered
X * up. A no-operation on systems where byte at a time terminal I/O is done.
X */
Xttflush()
X{
X   fflush(stdout);
X}
X
X/*
X * Read a character from the terminal, performing no editing and doing no echo
X * at all. More complex in VMS that almost anyplace else, which figures. Very
X * simple on CPM, because the system can do exactly what you want.
X */
Xttgetc()
X{
X    if( kbdqp )
X        kbdqp = FALSE;
X    else
X    {
X        if( kbdpoll && fcntl( 0, F_SETFL, kbdflgs ) < 0 )
X            return FALSE;
X        kbdpoll = FALSE;
X        while (read(0, &kbdq, 1) != 1)
X            ;
X    }
X    return ( kbdq & 127 );
X}
X
X/* typahead():    Check to see if any characters are already in the
X        keyboard buffer
X*/
Xttkeyready ()
X{
X    if( !kbdqp )
X    {
X        if( !kbdpoll && fcntl( 0, F_SETFL, kbdflgs | O_NDELAY ) < 0 )
X            return(FALSE);
X        kbdpoll = TRUE;    /*  fix in 1.13 */
X        kbdqp = (1 == read( 0, &kbdq, 1 ));
X    }
X    return ( kbdqp );
X}
X#endif
X
END_OF_FILE
if test 3581 -ne `wc -c <'termio.c'`; then
    echo shar: \"'termio.c'\" unpacked with wrong size!
fi
# end of 'termio.c'
fi
if test -f 'tty.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tty.c'\"
else
echo shar: Extracting \"'tty.c'\" \(6972 characters\)
sed "s/^X//" >'tty.c' <<'END_OF_FILE'
X/*
X*    Wang PC terminal display        TTY.C
X*
X*/
X#include        "def.h"
X
Xvoid    ttinit ();
Xvoid    tttidy ();
Xvoid    ttmove ();
Xvoid    tteeol ();
Xvoid    tteeop ();
Xvoid    ttbeep ();
Xvoid    asciiparm ();
Xvoid    ttnowindow ();    /* stub */
Xvoid    ttcolor ();
Xextern void tcapopen ();
Xextern void tcapmove ();
X 
X#if     GOSLING
Xvoid    ttinsl ();
Xvoid    ttdell ();
X#endif
X
X#include    "lintfunc.dec"
X#ifdef MSDOS
X#include    "dos.h"
Xextern  bool    ibm_pc, mem_map;
X#endif
X#define BEL     0x07            /* BEL character.               */
X#define ESC     0x1B            /* ESC character.               */
X
Xextern int  ttrow;
Xextern int  ttcol;
Xextern int  tttop;
Xextern int  ttbot;
Xextern int  tthue;
X
Xint     tceeol = 3;             /* Costs.                       */
Xint     rowb = NROW;  
X
X/*
X* Initialize the terminal when the editor
X* gets started up.
X*/
Xvoid    ttinit ()
X{
X#ifdef MSDOS
X    ttraw ();
X#endif
X#ifdef UNIX 
X	tcapopen();
X#endif
X}
X
X/*
X* Clean up the terminal, in anticipation of
X* a return to the command interpreter.
X*/
Xvoid    tttidy ()
X{
X#ifdef MSDOS
X    ttcooked ();
X#endif
X}
X
X/*
X* Move the cursor to the specified
X* origin 0 row and column position. Try to
X* optimize out extra moves; redisplay may
X* have left the cursor in the right
X* location last time!
X*/
Xvoid    ttmove (row, col)
X{
X#ifdef MSDOS
X    union   REGS    regs;
X
X/* Move in both axes */
X    if (ibm_pc)
X        {
X        regs.h.ah = 2;
X        regs.h.dh = (char)row;
X        regs.h.dl = (char)col;
X        regs.h.bh = 0;
X        int86 (0x10, &regs, &regs); /* set cursor position */
X        }
X    else
X#endif
X#ifdef UNIX
X	tcapmove(row, col);
X#endif
X#if ANSI
X        {
X        ttputc (ESC);
X        ttputc ('[');
X        asciiparm (row + 1);
X        ttputc (';');
X        asciiparm (col + 1);
X        ttputc ('H');
X        }
X#endif
X    ttrow = row;
X    ttcol = col;
X}
X
X/*
X* Erase to end of line.
X*/
Xvoid    tteeol ()
X{
X    char    col, row, i;
X#ifdef MSDOS
X    union   REGS    regs;
X
X    if (ibm_pc)
X        {
X        regs.h.ah = 3;
X        regs.h.bh = 0;
X        int86 (0x10, &regs, &regs); /* get cursor position */
X        col = regs.h.dl;    
X        row = regs.h.dh;
X        for (i = col ; i < (NCOL - 1); i++)
X            {
X            regs.h.ah = 0x0e;
X            regs.h.bl = 0;
X            regs.h.bh = 0;
X            regs.h.al = ' ';
X            int86 (0x10, &regs, &regs); /* set cursor position */
X            }
X        /* put cursor back to original position */
X        regs.h.ah = 2;
X        regs.h.bh = 0;
X        regs.h.dl = col;    
X        regs.h.dh = row;
X        int86 (0x10, &regs, &regs); /* get cursor position */
X        }
X    else
X#endif
X#if ANSI
X        {
X        ttputc (ESC);
X        ttputc ('[');
X#ifdef MSDOS
X        if (ibm_pc)
X           ttputc ('0');    /* this is necessary in IBM PC's */
X#endif
X        ttputc ('K');
X        }
X#endif
X#ifdef UNIX
X	tcapeeol();
X#endif
X    }
X
X/*
X* Erase to end of page.
X* only ever used when cursor is at 0,0, so IBM screen erase
X* is same as eop
X*/
Xvoid    tteeop ()
X{
X#ifdef MSDOS
X    union   REGS    regs;
X    char    i, j;
X
X    if (ibm_pc)
X        {
X        for (j = 0 ; j < nrow; j++)
X            {
X            for (i = 0 ; i < NCOL; i++)
X                {
X                regs.h.ah = 0x0e;
X                regs.h.bl = 0;
X                regs.h.bh = 0;
X                regs.h.al = ' ';
X                int86 (0x10, &regs, &regs); /* set cursor position */
X                }
X            }
X        }
X    else
X#endif
X#if	ANSI
X        {
X        ttcolor (CTEXT);
X        ttputc (ESC);
X        ttputc ('[');
X#ifdef MSDOS
X        if (ibm_pc)
X            ttputc ('0');
X        else
X#endif
X            ttputc ('2');
X        ttputc ('J');
X        }
X#endif
X#ifdef UNIX
X	tcapeeop();
X#endif
X}
X
X/*
X* Make a noise.
X*/
Xvoid    ttbeep ()
X{
X    ttputc (BEL);
X    ttflush ();
X}
X
X/*
X* Convert a number to decimal
X* ascii, and write it out. Used to
X* deal with numeric arguments.
X*/
Xvoid    asciiparm (n)
Xregister int    n;
X{
X    register int    q;
X
X    q = n / 10;
X    if (q != 0)
X        asciiparm (q);
X    ttputc ((n % 10) + '0');
X}
X
X#if     GOSLING
X/*
X* Insert a block of blank lines onto the
X* screen, using a scrolling region that starts at row
X* "row" and extends down to row "bot".  Deal with the one
X* line case, which is a little bit special, with special
X* case code.
X*/
Xvoid    ttinsl (row, bot, nchunk)
X{
X    if (row == bot)
X        {
X    /* Funny case.          */
X        if (nchunk != 1)
X            abort ();
X        ttmove (row, 0);
X        tteeol ();
X        }
X    else
X        {
X    /* General case.        */
X        ttputc (ESC);
X        ttputc ('/');
X        asciiparm (row + 1);
X        ttputc (';');
X        asciiparm (bot + 1);
X        ttputc (';');
X        asciiparm (nchunk);
X        ttputc (';');
X        ttputc ('0');
X        ttputc ('S');
X        }
X}
X
X/*
X* Delete a block of lines, with the uppermost
X* line at row "row", in a screen slice that extends to
X* row "bot". The "nchunk" is the number of lines that have
X* to be deleted.  Watch for the pathalogical 1 line case,
X* where the scroll region is *not* the way to do it.
X* The block delete is used by the slightly more
X* optimal display code.
X*/
Xvoid    ttdell (row, bot, nchunk)
X{
X    if (row == bot)
X        {
X    /* Funny case.          */
X        if (nchunk != 1)
X            abort ();
X        ttmove (row, 0);
X        tteeol ();
X        }
X    else
X        {
X    /* General case.        */
X        ttputc (ESC);
X        ttputc ('/');
X        asciiparm (row + 1);
X        ttputc (';');
X        asciiparm (bot + 1);
X        ttputc (';');
X        asciiparm (nchunk);
X        ttputc (';');
X        ttputc ('1');
X        ttputc ('S');
X        }
X}
X#endif
X
X/*
X* Switch to full screen scroll. This is
X* used by "spawn.c" just before is suspends the
X* editor, and by "display.c" when it is getting ready
X* to exit.  This is a no-op.
X*/
Xvoid    ttnowindow (){}
X
X/*
X* Set the current writing color to the
X* specified color. Watch for color changes that are
X* not going to do anything (the color is already right)
X* and don't send anything to the display.
X*/
Xvoid    ttcolor (color)
Xregister int    color;
X{
X#ifdef MSDOS
X    if (mem_map)
X        {
X        tthue = color;          /* Save the color.      */
X        return;
X        }
X#endif
X#ifdef UNIX
X	if (color == CTEXT)
X		tcaprev (FALSE);
X	else	
X		tcaprev (TRUE);
X    tthue = color;          /* Save the color.      */
X#endif
X#if ANSI
X    if (color != tthue)
X        {
X        if (color == CTEXT)
X            {                   /* Normal video.        */
X            ttputc (ESC);
X            ttputc ('[');
X            ttputc ('0');
X            ttputc ('m');
X            }
X        else
X            if (color == CMODE)
X                {               /* Reverse video.       */
X                ttputc (ESC);
X                ttputc ('[');
X                ttputc ('7');
X                ttputc ('m');
X                }
X        tthue = color;          /* Save the color.      */
X        }
X#endif
X}
END_OF_FILE
if test 6972 -ne `wc -c <'tty.c'`; then
    echo shar: \"'tty.c'\" unpacked with wrong size!
fi
chmod +x 'tty.c'
# end of 'tty.c'
fi
if test -f 'ttyio.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ttyio.c'\"
else
echo shar: Extracting \"'ttyio.c'\" \(3623 characters\)
sed "s/^X//" >'ttyio.c' <<'END_OF_FILE'
X/*
X*
X*   MS-DOS terminal I/O.               TTYIO.C
X*/
X#if MSDOS
X#include        "def.h"
X
Xvoid    ttopen ();
Xvoid    ttclose (); /* stub */
Xvoid    ttputc ();
Xvoid    putline ();
Xvoid    ttflush (); /* stub */
Xint     ttkeyready ();
Xint     ttgetc ();
Xvoid    ttraw ();
Xvoid    ttcooked ();
Xint     set_crt_type ();
X#if RUNCHK  
Xchar    ERR_bd_pl[];
X#endif
X#include    "lintfunc.dec"
X#include    "dos.h"
X
Xint     slot;
Xint     scr_type;
X#define SCREEN_PORT (video_port)
Xstatic int  video_port =
X{0x1010
X};
X
Xextern  bool    wang_pc;
Xextern  bool    ibm_pc;
Xint     nrow;                   /* Terminal size, rows.         */
Xint     ncol;                   /* Terminal size, columns.      */
Xint     last_key;
X
X/*
X* Initialization.
X* Almost no operation in MS-DOS.
X*/
Xvoid ttopen ()
X{
X    if (wang_pc && !ibm_pc)
X        set_crt_type ();
X    nrow = NROW;
X    ncol = NCOL;
X}
X
Xvoid ttclose ()
X{
X}
Xvoid ttflush ()
X{
X}
X/*
X* Write character.
X*/
Xvoid ttputc (c)
X{
X    bdos (6, c, 0);
X}
X
Xvoid putline (row, startcol, stringsize, string)
Xint     row,
X        startcol,
X        stringsize;
Xchar   *string;
X{
X    extern int  tthue;
X    unsigned short *screen;
X    int     x,
X            attribute;
X    char    c_row, c_col, i;
X    union   REGS    regs;
X
X    if (ibm_pc)
X        {
X        c_row = row - 1;
X        c_col = startcol - 1;
X        for (i = 0; i < stringsize; i++)
X            {
X            regs.h.ah = 2;
X            regs.h.dh = c_row;
X            regs.h.dl= c_col;
X            regs.h.bh = 0;
X            int86 (0x10, &regs, &regs); /* set cursor position */
X        
X            if (tthue == CTEXT)
X                regs.h.bl = 0x07;
X            if (tthue == CMODE)
X                regs.h.bl = 0x70;
X            regs.h.ah = 9;
X            regs.h.bh = 0;
X            regs.h.al = string[i];
X            regs.x.cx= 1;
X            int86 (0x10, &regs, &regs); /* set cursor position */
X            c_col++;
X            }
X        }
X    else if (wang_pc)
X        {
X        if (tthue == CTEXT)
X            attribute = 0x00;
X        else
X            attribute = 0x02;
X
X        x = stringsize;
X        screen = (unsigned short *) WANG_CHARACTER_SCREEN;
X        screen += ((row - 1) * 80) + startcol - 1;
X        outp (SCREEN_PORT, 01);
X        while (x--)
X            {
X            *screen = (*string++ << 8) | attribute;
X            screen++;
X            }
X        outp (SCREEN_PORT, 00);
X        }
X}
X
X/* 
X*   return with a TRUE if key was struck.
X*/
Xint     ttkeyready ()
X{
X	int	cnt;
X
X    if (last_key != 0)
X        return (1);
X
X    last_key = bdos (6, 0xff, 0);
X    last_key &= 0xff;
X    if (last_key == 0)
X        return (0);
X    else
X        return (1);
X}
X
X/*
X* Read character.
X*/
Xint     ttgetc ()
X{
X    int     c;
X    if (last_key != 0)
X        {
X        c = last_key;
X        last_key = 0;
X        return (c);
X        }
X    ttcooked ();
X    c = (bdos (7, 0, 0) & 0xFF);
X    ttraw ();
X    return (c);
X}
X
X/* disable nasty cntrl-c during disk io!
X*/
Xvoid ttraw ()
X{
X    union REGS inregs, outregs;
X
X    inregs.h.al = 1;
X    inregs.h.ah = 0x33;
X    inregs.h.dl = 0;
X    intdos (&inregs, &outregs);
X/*
X    cntrlcoff();
X*/
X}
X
X/* re enable cntrl-c for keyboard 
X*/
Xvoid ttcooked ()
X{
X    union REGS inregs, outregs;
X
X    inregs.h.al = 1;
X    inregs.h.ah = 0x33;
X    intdos (&inregs, &outregs);
X    inregs.h.dl = 1;
X/*
X    cntrlcon();
X*/
X}
X
X/* switch physical monitors
X*/
Xstatic char str[] =
X{0x1b, '/', 1, 's'
X};
X
Xint     set_crt_type ()
X{
X    char    active_screen;
X
X    active_screen = getscreenstate ();
X    slot = active_screen & 0x0f;
X    scr_type = (active_screen & 0x70) >> 4;
X    video_port = 0x1010 | (slot << 8);
X}
X#endif
END_OF_FILE
if test 3623 -ne `wc -c <'ttyio.c'`; then
    echo shar: \"'ttyio.c'\" unpacked with wrong size!
fi
chmod +x 'ttyio.c'
# end of 'ttyio.c'
fi
if test -f 'wangpc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'wangpc.c'\"
else
echo shar: Extracting \"'wangpc.c'\" \(3557 characters\)
sed "s/^X//" >'wangpc.c' <<'END_OF_FILE'
X#define LINT_ARGS   1           /* enable lint type checking */
X#include "def.h"
X#include    "lintfunc.dec"
X#if MSDOS
X#include "dos.h"
X
Xtypedef struct SCREENINFO
X{
X    unsigned char   state;
X    unsigned char   scanoff;
X    unsigned short  bufseg;
X    unsigned char   colors;
X    unsigned char   row;
X    unsigned char   col;
X    unsigned char   attr;
X    unsigned char   auxmod;
X    unsigned char   auxmod2;
X} SCREENINFO;
X
Xtypedef struct SYSCONFIG
X{
X    unsigned short  version;
X    unsigned short  memsize;
X    unsigned short  reserved[2];
X    unsigned short  screen_count;
X    unsigned short  screens[4];
X} SYSCONFIG;
X
X#define SENDCHAR 6
X#define SENDLINE 0x0d
X#define BIOS 0x88
X#define GETSYSCON 1
X
Xbool    wang_pc = FALSE;
Xbool    ibm_pc = FALSE;
Xbool    mem_map = FALSE;
X
Xvoid    is_wang ()
X    {
X    union REGS inregs, outregs;
X    struct SREGS    segregs;
X    unsigned char far *memptr;
X    unsigned char    c;
X    int     i;
X    static  char wang_id[] = {"WANG"};
X    static  char ret_str[6];
X    char    *chr_ptr;
X
X    chr_ptr = ret_str;
X    /* test for Wang PC */
X    memptr = (unsigned char far *)0xFC003FC2L;
X    wang_pc = TRUE;
X    for (i=0;(i<4 && wang_pc);i++)
X        {
X        if(*memptr != wang_id[i])
X            wang_pc = FALSE;
X        memptr++;
X        }
X
X    if (wang_pc)
X        {
X        mem_map = TRUE;
X        ret_str[0] = 0xFF;      /* set to known value */
X        mem_map = TRUE;
X        inregs.h.al = 0x02;
X        inregs.h.ah = 0x44;
X        inregs.x.bx = 0;
X        inregs.x.cx = 1;
X        inregs.x.dx = FP_OFF (chr_ptr);
X        segregs.ds = FP_SEG (chr_ptr);
X    
X        int86x (0x21, &inregs, &outregs, &segregs);
X        if (ret_str[0] == 0x11)
X            {
X            ibm_pc = TRUE;
X            return;
X            }
X        ibm_pc = FALSE;
X        return;
X        }
X
X    /* Must be an IBM or clone */
X    memptr = (unsigned char far *)0xF000FFFEL;
X    c = *memptr;
X    switch(c)
X        {
X        case 0xFC:  /* IBM AT or clone */
X        case 0xFD:  /* IBM PC Jr */
X        case 0xFE:  /* IBM XT or clone */
X        case 0xFF:  /* IBM PC or clone */
X            mem_map = TRUE;
X            ibm_pc = TRUE;
X            return;
X        }
X    }
X
Xint     getsysconfig (outregs, segregs)
X        union REGS * outregs;
Xstruct SREGS   *segregs;
X{
X    union REGS inregs;
X
X    inregs.h.al = GETSYSCON;
X
X    int86x (BIOS, &inregs, outregs, segregs);
X}
X
Xchar    getscreenstate ()
X{
X    struct SREGS    segregs;
X    union REGS outregs;
X
X    struct SYSCONFIG   *config;
X    struct SCREENINFO  *screeninfo;
X    unsigned short *shortptr;
X    unsigned int    screen_count;
X
X    getsysconfig (&outregs, &segregs);
X
X /* set pointer to force register info into a long pointer. */
X    shortptr = (unsigned short *) & config;
X
X /* Offset is first, it comes back in BX */
X    *shortptr = (unsigned short) outregs.x.bx;
X    shortptr++;
X
X /* segment is in ES */
X    *shortptr = (unsigned short) segregs.es;
X
X /* Now, the config pointer should be set to the config table. */
X/*  printf("Version = %04x \n",config->version);
X    printf("Memsize = %04x \n",config->memsize);
X    printf("Screens = %04x \n",config->screen_count);
X*/
X    screen_count = config -> screen_count;
X    while (screen_count)
X        {
X        shortptr = (unsigned short *) & screeninfo;
X        *shortptr = (unsigned short) config -> screens[screen_count - 1];
X        shortptr++;
X        *shortptr = (unsigned short) segregs.es;
X        if (screeninfo -> state & 0x80)
X            break;
X        screen_count--;
X        }
X    return (screeninfo -> state);
X}
X#endif
END_OF_FILE
if test 3557 -ne `wc -c <'wangpc.c'`; then
    echo shar: \"'wangpc.c'\" unpacked with wrong size!
fi
chmod +x 'wangpc.c'
# end of 'wangpc.c'
fi
if test -f 'word.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'word.c'\"
else
echo shar: Extracting \"'word.c'\" \(3025 characters\)
sed "s/^X//" >'word.c' <<'END_OF_FILE'
X/*
X*       Word mode commands.
X* The routines in this file
X* implement commands that work unit at
X* a time. There are all sorts of unit mode
X* commands. If I do any sentence and/or paragraph
X* mode commands, they are likely to be put in
X* this file.
X*/
X#define LINT_ARGS   1           /* enable lint type checking */
X#include    "def.h"
X
Xchar    forwunit ();
X
X#include    "lintfunc.dec"
X/*
X* Move the cursor backward by
X* "n" units. All of the details of motion
X* are performed by the "backchar" and "forwchar"
X* routines. Error if you try to move beyond
X* the buffers.
X*/
Xchar    backunit (f, n, k)
X{
X    char    ret;
X
X    if (n < 0)
X        return (forwunit (f, -n, KRANDOM));
X
X    curwp -> w_unit_offset = 0;
X    while (n--)
X        {
X        ret = move_ptr (curwp, -(long)R_B_PER_U(curwp), TRUE, TRUE, TRUE);
X        }
X    wind_on_dot (curwp);
X    curwp -> w_flag |= WFMODE;  /* update mode line */
X    return (ret);
X}
X
X
X/*
X* Move the cursor forward by
X* the specified number of units. All of the
X* motion is done by "forwchar". Error if you
X* try and move beyond the buffer's end.
X*/
Xchar    forwunit (f, n, k)
X{
X
X    if      (n < 0)
X                return (backunit (f, -n, KRANDOM));
X
X    curwp -> w_unit_offset = 0;
X    while (n--)
X        {
X        move_ptr (curwp, (long)R_B_PER_U(curwp), TRUE, TRUE, TRUE);
X        }
X    wind_on_dot (curwp);
X    curwp -> w_flag |= WFMODE;  /* update mode line */
X    return (TRUE);
X}
X
X
X/*
X* Kill forward by "n" units. The rules for final
X* status are now different. It is not considered an error
X* to delete fewer units than you asked. This lets you say
X* "kill lots of units" and have the command stop in a reasonable
X* way when it hits the end of the buffer.
X*/
Xbool delfunit (f, n, k)
X{
X    register    LINE * dotp;
X    register int    doto;
X
X    if (n < 0)
X        return (FALSE);
X    if ((lastflag & CFKILL) == 0)/* Purge kill buffer.   */
X        kdelete ();
X    thisflag |= CFKILL;
X    while (n--)
X        {
X        ldelete (R_B_PER_U(curwp), TRUE);
X        }
X    curwp -> w_flag |= WFHARD;
X    curwp -> w_unit_offset = 0;
X    return (TRUE);
X}
X
X
X/*
X* Kill backwards by "n" units. The rules
X* for success and failure are now different, to prevent
X* strange behavior at the start of the buffer. The command
X* only fails if something goes wrong with the actual delete
X* of the characters. It is successful even if no characters
X* are deleted, or if you say delete 5 units, and there are
X* only 4 units left. I considered making the first call
X* to "backchar" special, but decided that that would just
X* be wierd. Normally this is bound to "M-Rubout" and
X* to "M-Backspace".
X*/
Xbool delbunit (f, n, k)
X{
X    int size;
X
X    if (n < 0)
X        return (FALSE);
X    if ((lastflag & CFKILL) == 0)/* Purge kill buffer.   */
X        kdelete ();
X    thisflag |= CFKILL;
X    size = R_B_PER_U(curwp);
X    while (n--)
X        {
X        if (move_ptr (curwp, -((long)size), TRUE, TRUE, TRUE))
X            ldelete (size, TRUE);
X        }
X    curwp -> w_flag |= WFHARD;
X    return (TRUE);
X}
X
END_OF_FILE
if test 3025 -ne `wc -c <'word.c'`; then
    echo shar: \"'word.c'\" unpacked with wrong size!
fi
chmod +x 'word.c'
# end of 'word.c'
fi
echo shar: End of archive 1 \(of 10\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

-- 
>>>>>>>>>>>>>>>> Peter Reilley ..... pvr@wang.com <<<<<<<<<<<<<<<<<<<<<<<
                     Well, that about says it.

pvr@wang.com (Peter Reilley) (06/06/91)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 10)."
# Contents:  echo.c format.c ttykbd.c window.c
# Wrapped by pvr@elf on Thu Mar 14 08:16:46 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'echo.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'echo.c'\"
else
echo shar: Extracting \"'echo.c'\" \(9451 characters\)
sed "s/^X//" >'echo.c' <<'END_OF_FILE'
X/*
X*       Echo line reading and writing.
X* Common routines for reading
X* and writing characters in the echo line area
X* of the display screen. Used by the entire
X* known universe.
X*/
X#include    "def.h"
X
Xvoid    eerase ();
Xchar    ereply ();
Xchar    eread ();
Xvoid    eformat ();
Xvoid    eputi ();
Xvoid    eputs ();
Xvoid    eputc ();
X
X
Xextern    char    MSG_null[];
Xextern    char    MSG_y_n[];
Xextern    char    MSG_hex_dig[];
X
X#include    "lintfunc.dec"
Xint     epresf = FALSE;         /* Stuff in echo line flag. */
X
X/*
X* Erase the echo line.
X*/
Xvoid eerase ()
X{
X    writ_echo (MSG_null);  /* clear the echo line */
X    epresf = FALSE;
X}
X
X
X/*
X* Ask "yes" or "no" question.
X* Return ABORT if the user answers the question
X* with the abort ("^G") character. Return FALSE
X* for "no" and TRUE for "yes". No formatting
X* services are available.
X*/
Xchar    eyesno (sp)
Xchar   *sp;
X{
X
X    register char   s;
X    char    buf[64];
X
X    for (;;)
X        {
X
X        s = ereply (MSG_y_n, buf, sizeof (buf), sp);
X        if (s == ABORT)
X            return (ABORT);
X        if (s != FALSE)
X            {
X
X            if (buf[0] == 'y' || buf[0] == 'Y')
X                return (TRUE);
X            if (buf[0] == 'n' || buf[0] == 'N')
X                return (FALSE);
X            }
X
X        }
X
X}
X
X
X/*
X* Write out a prompt, and read back a
X* reply. The prompt is now written out with full "eprintf"
X* formatting, although the arguments are in a rather strange
X* place. This is always a new message, there is no auto
X* completion, and the return is echoed as such.
X*/
X/* VARARGS3 */
Xchar    ereply (fp, buf, nbuf, arg)
Xchar   *fp;
Xchar   *buf;
Xint     nbuf;
Xchar   *arg;
X{
X    return (eread (fp, buf, nbuf, EFNEW | EFCR, arg));
X}
X
X
X/*
X* This is the general "read input from the
X* echo line" routine. The basic idea is that the prompt
X* string "prompt" is written to the echo line, and a one
X* line reply is read back into the supplied "buf" (with
X* maximum length "len"). The "flag" contains EFNEW (a
X* new prompt), an EFAUTO (autocomplete), or EFCR (echo
X* the carriage return as CR).
X*/
Xchar    eread (fp, buf, nbuf, flag, ap)
Xchar   *fp;
Xchar   *buf;
Xchar   *ap;
X{
X
X    register int    cpos;
X    register    SYMBOL * sp1;
X    register    SYMBOL * sp2;
X    register int    i;
X    register int    c;
X    register int    h;
X    register int    nhits;
X    register int    nxtra;
X    register int    bxtra;
X
X    int     quote_flag;
X
X    quote_flag = 0;
X    cpos = 0;
X    if (kbdmop != NULL)
X        {
X    /* In a macro.      */
X        while ((c = *kbdmop++) != '\0')
X            buf[cpos++] = c;
X        buf[cpos] = '\0';
X        goto done;
X        }
X
X    if ((flag & EFNEW) != 0 || ttrow != nrow - 1)
X        {
X
X        ttcolor (CTEXT);
X        ttmove (nrow - 1, 0);
X        epresf = TRUE;
X        }
X    else
X        eputc (' ');
X    eformat (fp, ap);
X    tteeol ();
X    ttflush ();
X    for (;;)
X        {
X        c = getkey ();
X        if (c == ' ' && (flag & EFAUTO) != 0)
X            {
X            nhits = 0;
X            nxtra = HUGE;
X            for (h = 0; h < NSHASH; ++h)
X                {
X                sp1 = symbol[h];
X                while (sp1 != NULL)
X                    {
X                    for (i = 0; i < cpos; ++i)
X                        {
X                        if (buf[i] != sp1 -> s_name[i])
X                            break;
X                        }
X
X                    if (i == cpos)
X                        {
X                        if (nhits == 0)
X                            sp2 = sp1;
X                        ++nhits;
X                        bxtra = getxtra (sp1, sp2, cpos);
X                        if (bxtra < nxtra)
X                            nxtra = bxtra;
X                        }
X
X                    sp1 = sp1 -> s_symp;
X                    }
X                }
X
X            if (nhits == 0)     /* No completion.   */
X                continue;
X            for (i = 0; i < nxtra && cpos < nbuf - 1; ++i)
X                {
X                c = sp2 -> s_name[cpos];
X                buf[cpos++] = c;
X                eputc (c);
X                }
X
X            ttflush ();
X            if (nhits != 1)     /* Fake a CR if there   */
X                continue;       /* is 1 choice.     */
X            c = (KCTRL | 'M');
X            }
X        if (quote_flag)
X            {
X            c = c & 0x1f;
X            quote_flag = 0;
X            }
X
X
X        switch (c)
X            {
X            case (KCTRL | 'Q'): 
X                quote_flag = 1;
X                break;
X            case (KCTRL | 'M'): /* Return, done.    */
X                buf[cpos] = '\0';
X                if (kbdmip != NULL)
X                    {
X                    if (kbdmip + cpos + 1 > &kbdm[NKBDM - 3])
X                        {
X                        (void) ctrlg (FALSE, 0, KRANDOM);
X                        ttflush ();
X                        return (ABORT);
X                        }
X
X                    for (i = 0; i < cpos; ++i)
X                        *kbdmip++ = buf[i];
X                    *kbdmip++ = '\0';
X                    }
X
X                if ((flag & EFCR) != 0)
X                    {
X                    ttputc (0x0D);
X                    ttflush ();
X                    }
X
X                goto done;
X
X            case (KCTRL | 'G'): /* Bell, abort.     */
X                eputc (0x07);
X                (void) ctrlg (FALSE, 0, KRANDOM);
X                ttflush ();
X                return (ABORT);
X
X            case 0x7F:          /* Rubout, erase.   */
X            case (KCTRL | 'H'): /* Backspace, erase.    */
X                if (cpos != 0)
X                    {
X                    ttputc ('\b');
X                    ttputc (' ');
X                    ttputc ('\b');
X                    --ttcol;
X                    if (ISCTRL (buf[--cpos]) != FALSE)
X                        {
X                        ttputc ('\b');
X                        ttputc (' ');
X                        ttputc ('\b');
X                        --ttcol;
X                        }
X
X                    ttflush ();
X                    }
X                break;
X
X            case (KCTRL | 'U'): /* C-U, kill line.  */
X                while (cpos != 0)
X                    {
X                    ttputc ('\b');
X                    ttputc (' ');
X                    ttputc ('\b');
X                    --ttcol;
X                    if (ISCTRL (buf[--cpos]) != FALSE)
X                        {
X                        ttputc ('\b');
X                        ttputc (' ');
X                        ttputc ('\b');
X                        --ttcol;
X                        }
X
X                    }
X
X                ttflush ();
X                break;
X
X            default:            /* All the rest.    */
X                if ((cpos < nbuf - 1) && ((c & ~KCHAR) == 0))
X                    {
X                    buf[cpos++] = c;
X                    eputc (c);
X                    ttflush ();
X                    }
X            }                   /* End switch */
X
X        }
X
Xdone: 
X    if (buf[0] == '\0')
X        return (FALSE);
X    return (TRUE);
X}
X
X
X/*
X* The "sp1" and "sp2" point to extended command
X* symbol table entries. The "cpos" is a horizontal position
X* in the name. Return the longest block of characters that can
X* be autocompleted at this point. Sometimes the two symbols
X* are the same, but this is normal.
X*/
Xint     getxtra (sp1, sp2, cpos)
XSYMBOL * sp1;
XSYMBOL * sp2;
X{
X
X    register int    i;
X
X    i = cpos;
X    for (;;)
X        {
X
X        if (sp1 -> s_name[i] != sp2 -> s_name[i])
X            break;
X        if (sp1 -> s_name[i] == '\0')
X            break;
X        ++i;
X        }
X
X    return (i - cpos);
X}
X
X/*
X* Printf style formatting. This is
X* called by both "eprintf" and "ereply", to provide
X* formatting services to their clients. The move to the
X* start of the echo line, and the erase to the end of
X* the echo line, is done by the caller.
X*/
Xvoid eformat (fp, ap)
Xchar  *fp;
Xchar  *ap;
X{
X
X    register int    c;
X
X    while ((c = *fp++) != '\0')
X        {
X
X        if (c != '%')
X            eputc (c);
X        else
X            {
X
X            c = *fp++;
X            switch (c)
X                {
X
X                case 'd': 
X                    eputi (*(int *) ap, 10);
X                    ap += sizeof (int);
X                    break;
X
X                case 'x':       /* krw */
X                    eputi (*(int *) ap, 16);
X                    ap += sizeof (int);
X                    break;
X
X                case 'o': 
X                    eputi (*(int *) ap, 8);
X                    ap += sizeof (int);
X                    break;
X
X                case 's': 
X                    eputs (ap);
X                    ap += sizeof (char *);
X                    break;
X
X                default: 
X                    eputc (c);
X                }
X
X            }
X
X        }
X
X}
X
X
X/*
X* Put integer, in radix "r".
X*/
Xvoid eputi (i, r)
Xint    i;
Xint    r;
X{
X    static char *convert =
X    {
X        MSG_hex_dig
X    }
X               ;
X
X    register int    q;
X
X    if ((q = i / r) != 0)
X        eputi (q, r);
X    eputc (convert[i % r]);
X
X}
X
X
X/*
X* Put string.
X*/
Xvoid eputs (s)
Xchar  *s;
X{
X    register int    c;
X
X    while ((c = *s++) != '\0')
X        eputc (c);
X}
X
X
X/*
X* Put character. Watch for
X* control characters, and for the line
X* getting too long.
X*/
Xvoid eputc (c)
Xint    c;
X{
X
X    if (ttcol < ncol)
X        {
X
X        if (ISCTRL (c) != FALSE)
X            {
X
X            eputc ('^');
X            c ^= 0x40;
X            }
X
X        ttputc (c);
X        ++ttcol;
X        }
X
X}
X
END_OF_FILE
if test 9451 -ne `wc -c <'echo.c'`; then
    echo shar: \"'echo.c'\" unpacked with wrong size!
fi
chmod +x 'echo.c'
# end of 'echo.c'
fi
if test -f 'format.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'format.c'\"
else
echo shar: Extracting \"'format.c'\" \(8417 characters\)
sed "s/^X//" >'format.c' <<'END_OF_FILE'
X/*
X* The module devines the format of the screen display.
X*/
X
X#define LINT_ARGS   1           /* enable lint type checking */
X#include    "def.h"
X#include    "lintfunc.dec"
X
X
Xextern    char    hex_str[];
Xextern    char    hex_l_str[];
Xextern    char    octal_str[];
Xextern    char    octal_l_str[];
Xextern    char    decimal_str[];
Xextern    char    decimal_l_str[];
Xextern    char    char_str[];
X
X
X/* These structures contain the format for the displayed line */
X
X
X#define FC 13
X#define FS 0
X
Xuchar    ascii_s_posn[] =
X{FS+0, FS+1, FS+2, FS+3, FS+4, FS+5, FS+6, FS+7, FS+8, FS+9,
XFS+10, FS+11, FS+12, FS+13, FS+14, FS+15, FS+16, FS+17, FS+18, FS+19,
XFS+20, FS+21, FS+22, FS+23, FS+24, FS+25, FS+26, FS+27, FS+28, FS+29,
XFS+30, FS+31, FS+32, FS+33, FS+34, FS+35, FS+36, FS+37, FS+38, FS+39,
XFS+40, FS+41, FS+42, FS+43, FS+44, FS+45, FS+46, FS+47, FS+48, FS+49,
XFS+50, FS+51, FS+52, FS+53, FS+54, FS+55, FS+56, FS+57, FS+58, FS+59,
XFS+60, FS+61, FS+62, FS+63, FS+64, FS+65, FS+66, FS+67, FS+68, FS+69,
XFS+70, FS+71, FS+72, FS+73, FS+74, FS+75, FS+76, FS+77, FS+78, FS+79,
X};
X
XROW_FMT text_fmt =
X{TEXT, BYTES, 128, 128, 128, 1, 1, FALSE, char_str, hex_l_str, hex_str,
X ascii_s_posn, 0};
X
XROW_FMT ascii_fmt =
X{ASCII, BYTES, 64, 64, 64, 1, 1, FALSE, char_str, hex_l_str, hex_str,
X &ascii_s_posn[FC], 0};
X
XROW_FMT ascii_s_fmt =
X{ASCII, BYTES, 32, 32, 1, 1, 1, FALSE,  char_str, hex_l_str, hex_str,
X ascii_s_posn, 0};
X
XROW_FMT ebcdic_fmt =
X{EBCDIC, BYTES, 64, 64, 64, 1, 1, FALSE, char_str, hex_l_str, hex_str,
X &ascii_s_posn[FC], 0};
X
XROW_FMT ebcdic_s_fmt =
X{EBCDIC, BYTES, 32, 32, 1, 1, 1, FALSE, char_str, hex_l_str, hex_str,
X ascii_s_posn, 0};
X
Xuchar    octal_8_posn[] =
X{FC, FC + 4, FC + 8, FC + 12, FC + 16, FC + 20,
X    FC + 24, FC + 28, FC + 33, FC + 37, FC + 41,
X    FC + 45, FC + 49, FC + 53, FC + 57, FC + 61
X};
X
XROW_FMT octal_8_fmt =
X{OCTAL, BYTES, 16, 16, 16, 1, 3, TRUE, octal_str, octal_l_str, octal_str,
X octal_8_posn, 0};
X
Xuchar    octal_s_8_posn[] =
X{FS, FS + 4, FS + 8, FS + 12, FS + 16, FS + 20,
X    FS + 24, FS + 28, FS + 32, FS + 36, FS + 40,
X    FS + 44, FS + 48, FS + 52, FS + 56, FS + 60,
X    FS + 64, FS + 68, FS + 72, FS + 76, FS + 80
X};
XROW_FMT octal_s_8_fmt =
X{OCTAL, BYTES, 8, 8, 1, 1, 3, TRUE, octal_str, octal_l_str, octal_str,
X octal_s_8_posn, 0};
X
Xuchar    octal_16_posn[] =
X{FC, FC + 7, FC + 14, FC + 21, FC + 29, FC + 36, FC + 43, FC + 50
X};
X
XROW_FMT octal_16_fmt =
X{OCTAL, WORDS, 8, 16, 16, 2, 6, TRUE, octal_str, octal_l_str, octal_str,
X octal_16_posn, 0};
X
Xuchar    octal_s_16_posn[] =
X{FS, FS + 7, FS + 14, FS + 21, FS + 28, FS + 35,
X FS + 42, FS + 49, FS + 56, FS + 63, FS + 70, FS + 77
X};
XROW_FMT octal_s_16_fmt =
X{OCTAL, WORDS, 4, 8, 2, 2, 6, TRUE, octal_str, octal_l_str, octal_str,
X octal_s_16_posn, 0};
X
Xuchar    octal_32_posn[] =
X{FC, FC + 12, FC + 25, FC + 37
X};
X
XROW_FMT octal_32_fmt =
X{OCTAL, DWORDS, 4, 16, 16, 4, 11, TRUE, octal_l_str, octal_l_str, octal_str,
X octal_32_posn, 0};
X
Xuchar    octal_s_32_posn[] =
X{FS, FS + 12, FS + 24, FS + 36, FS + 48, FS + 60, FS + 72
X};
XROW_FMT octal_s_32_fmt =
X{OCTAL, DWORDS, 2, 8, 4, 4, 11, TRUE, octal_l_str, octal_l_str, octal_str,
X octal_s_32_posn, };
X
XROW_FMT decimal_8_fmt =
X{DECIMAL, BYTES, 16, 16, 16, 1, 3, TRUE, decimal_str, decimal_l_str, decimal_str,
X octal_8_posn, 0};
X
XROW_FMT decimal_s_8_fmt =
X{DECIMAL, BYTES, 8, 8, 1, 1, 3, TRUE, decimal_str, decimal_l_str, decimal_str,
X octal_s_8_posn, 0};
X
Xuchar    decimal_16_posn[] =
X{FC, FC + 6, FC + 12, FC + 18, FC + 25,
X    FC + 31, FC + 37, FC + 43
X};
X
XROW_FMT decimal_16_fmt =
X{DECIMAL, WORDS, 8, 16, 16, 2, 5, TRUE, decimal_str, decimal_l_str, decimal_str,
X decimal_16_posn, 0};
X
Xuchar    decimal_s_16_posn[] =
X{FS, FS + 6, FS + 12, FS + 18, FS + 24,
X    FS + 30, FS + 36, FS + 42, FS + 48,
X    FS + 54, FS + 60, FS + 66, FS + 72, FS + 78
X};
XROW_FMT decimal_s_16_fmt =
X{DECIMAL, WORDS, 4, 8, 2, 2, 5, TRUE, decimal_str, decimal_l_str, decimal_str,
X decimal_s_16_posn, 0};
X
Xuchar    decimal_32_posn[] =
X{FC, FC + 11, FC + 23, FC + 34
X};
X
XROW_FMT decimal_32_fmt =
X{DECIMAL, DWORDS, 4, 16, 16, 4, 10, TRUE, decimal_l_str, decimal_l_str, decimal_str,
X decimal_32_posn, 0};
X
Xuchar    decimal_s_32_posn[] =
X{FS, FS + 11, FS + 22, FS + 33, FS + 44, FS + 55, FS + 66, FS + 77
X};
XROW_FMT decimal_s_32_fmt =
X{DECIMAL, DWORDS, 4, 16, 4, 4, 10, TRUE, decimal_l_str, decimal_l_str, decimal_str,
X decimal_s_32_posn, 0};
X
Xuchar    hex_8_posn[] =
X{FC, FC + 3, FC + 6, FC + 9, FC + 12, FC + 15,
X    FC + 18, FC + 21, FC + 25, FC + 28, FC + 31,
X    FC + 34, FC + 37, FC + 40, FC + 43, FC + 46,
X    FC + 50, FC + 51, FC + 52, FC + 53, FC + 54,
X    FC + 55, FC + 56, FC + 57, FC + 58, FC + 59,
X    FC + 60, FC + 61, FC + 62, FC + 63, FC + 64,
X    FC + 65
X};
X
XROW_FMT hex_8_fmt =
X{HEX, BYTES, 16, 16, 16, 1, 2, TRUE, hex_str, hex_l_str, hex_str,
X hex_8_posn, 0};
X
X
Xuchar    hex_s_8_posn[] =
X{FS, FS + 3, FS + 6, FS + 9, FS + 12, FS + 15,
X    FS + 18, FS + 21, FS + 24, FS + 27, FS + 30,
X    FS + 33, FS + 36, FS + 39, FS + 42, FS + 45,
X    FS + 48, FS + 51, FS + 54, FS + 57, FS + 60,
X    FS + 63, FS + 66, FS + 69, FS + 72, FS + 75,
X    FS + 78, FS + 80, FS + 80, FS + 80, FS + 80,
X    FS + 80
X};
XROW_FMT hex_s_8_fmt =
X{HEX, BYTES, 8, 8, 1, 1, 2, TRUE, hex_str, hex_l_str, hex_str,
X hex_s_8_posn, 0};
X
Xuchar    hex_16_posn[] =
X{FC, FC + 5, FC + 10, FC + 15, FC + 21, FC + 26, FC + 31, FC + 36
X};
X
XROW_FMT hex_16_fmt =
X{HEX, WORDS, 8, 16, 16, 2, 4, TRUE, hex_str, hex_l_str, hex_str,
X hex_16_posn, 0};
X
Xuchar    hex_s_16_posn[] =
X{FS, FS + 5, FS + 10, FS + 15, FS + 20, FS + 25,
X FS + 30, FS + 35, FS + 40, FS + 45, FS + 50,
X FS + 55, FS + 60, FS + 65, FS + 70, FS + 75
X};
XROW_FMT hex_s_16_fmt =
X{HEX, WORDS, 8, 16, 2, 2, 4, TRUE, hex_str, hex_l_str, hex_str,
X hex_s_16_posn, 0};
X
Xuchar    hex_32_posn[] =
X{FC, FC + 9, FC + 19, FC + 28
X};
X
XROW_FMT hex_32_fmt =
X{HEX, DWORDS, 4, 16, 16, 4, 8, TRUE, hex_l_str, hex_l_str, hex_str,
X hex_32_posn, 0};
X
Xuchar    hex_s_32_posn[] =
X{FS, FS + 9, FS + 18, FS + 27, FS + 36, FS + 45, FS + 54, FS + 63, FS + 72
X};
XROW_FMT hex_s_32_fmt =
X{HEX, DWORDS, 4, 16, 4, 4, 8, TRUE, hex_l_str, hex_l_str, hex_str,
X hex_s_32_posn, 0};
X
XROW_FMT binary_8_fmt =
X{BINARY, BYTES, 4, 4, 4, 1, 8, FALSE, hex_str, hex_l_str, hex_str,
X hex_32_posn, 0};  /* use the hex position array */
X
XROW_FMT binary_s_8_fmt =
X{BINARY, BYTES, 4, 4, 1, 1, 8, FALSE, hex_str, hex_l_str, hex_str,
X hex_s_32_posn, 0};  /* use the hex position array */
X
Xuchar    binary_16_posn[] =
X{FC, FC + 17, FC + 34, FC + 51
X};
X
XROW_FMT binary_16_fmt =
X{BINARY, WORDS, 4, 8, 8, 2, 16, FALSE, hex_str, hex_l_str, hex_str,
X binary_16_posn, 0};
X
Xuchar    binary_s_16_posn[] =
X{FS, FS + 17, FS + 34, FS + 51, FS + 68
X};
XROW_FMT binary_s_16_fmt =
X{BINARY, WORDS, 2, 4, 2, 2, 16, FALSE, hex_str, hex_l_str, hex_str,
X binary_s_16_posn, 0};
X
Xuchar    binary_32_posn[] =
X{FC, FC + 33
X};
X
XROW_FMT binary_32_fmt =
X{BINARY, DWORDS, 2, 8, 8, 4, 32, FALSE, hex_l_str, hex_l_str, hex_str,
X binary_32_posn, 0};
X
Xuchar    binary_s_32_posn[] =
X{FS, FS + 33
X};
XROW_FMT binary_s_32_fmt =
X{BINARY, DWORDS, 1, 4, 4, 4, 32, FALSE, hex_l_str, hex_l_str, hex_str,
X binary_s_32_posn, 0};
X
X/* I must do this because C does not allow forward initialization of
X	structures */
Xinit_fmt()
X	{
X	text_fmt.r_srch_fmt = &text_fmt;
X	ascii_fmt.r_srch_fmt = &ascii_s_fmt;
X	ascii_s_fmt.r_srch_fmt = &ascii_fmt;
X	ebcdic_fmt.r_srch_fmt = &ebcdic_s_fmt;
X	ebcdic_s_fmt.r_srch_fmt = &ebcdic_fmt;
X	octal_8_fmt.r_srch_fmt = &octal_s_8_fmt;
X	octal_s_8_fmt.r_srch_fmt = &octal_8_fmt;
X	octal_16_fmt.r_srch_fmt = &octal_s_16_fmt;
X	octal_s_16_fmt.r_srch_fmt = &octal_16_fmt;
X	octal_32_fmt.r_srch_fmt = &octal_s_32_fmt;
X	octal_s_32_fmt.r_srch_fmt = &octal_32_fmt;
X	decimal_8_fmt.r_srch_fmt = &decimal_s_8_fmt;
X	decimal_s_8_fmt.r_srch_fmt = &decimal_8_fmt;
X	decimal_16_fmt.r_srch_fmt = &decimal_s_16_fmt;
X	decimal_s_16_fmt.r_srch_fmt = &decimal_16_fmt;
X	decimal_32_fmt.r_srch_fmt = &decimal_s_32_fmt;
X	decimal_s_32_fmt.r_srch_fmt = &decimal_32_fmt;
X	hex_8_fmt.r_srch_fmt = &hex_s_8_fmt;
X	hex_s_8_fmt.r_srch_fmt = &hex_8_fmt;
X	hex_16_fmt.r_srch_fmt = &hex_s_16_fmt;
X	hex_s_16_fmt.r_srch_fmt = &hex_16_fmt;
X	hex_32_fmt.r_srch_fmt = &hex_s_32_fmt;
X	hex_s_32_fmt.r_srch_fmt = &hex_32_fmt;
X	binary_8_fmt.r_srch_fmt = &binary_s_8_fmt;
X	binary_s_8_fmt.r_srch_fmt = &binary_8_fmt;
X	binary_16_fmt.r_srch_fmt = &binary_s_16_fmt;
X	binary_s_16_fmt.r_srch_fmt = &binary_16_fmt;
X	binary_32_fmt.r_srch_fmt = &binary_s_32_fmt;
X	binary_s_32_fmt.r_srch_fmt = &binary_32_fmt;
X	}
END_OF_FILE
if test 8417 -ne `wc -c <'format.c'`; then
    echo shar: \"'format.c'\" unpacked with wrong size!
fi
chmod +x 'format.c'
# end of 'format.c'
fi
if test -f 'ttykbd.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ttykbd.c'\"
else
echo shar: Extracting \"'ttykbd.c'\" \(11412 characters\)
sed "s/^X//" >'ttykbd.c' <<'END_OF_FILE'
X/*
X *      Wang PC keyboard handler
X */
X#define LINT_ARGS   1           /* enable lint type checking */
X#include    "def.h"
X
Xextern    char    MSG_sp_key[];
Xextern    char    MSG_byte_shift[];
Xextern    char    MSG_back_char[];
Xextern    char    MSG_quit[];
Xextern    char    MSG_forw_del_char[];
Xextern    char    MSG_toggle_swap[];
Xextern    char    MSG_forw_char[];
Xextern    char    MSG_abort[];
Xextern    char    MSG_ins_self[];
Xextern    char    MSG_back_del_char[];
Xextern    char    MSG_refresh[];
Xextern    char    MSG_forw_line[];
Xextern    char    MSG_back_line[];
Xextern    char    MSG_quote[];
Xextern    char    MSG_recall[];
Xextern    char    MSG_twiddle[];
Xextern    char    MSG_forw_page[];
Xextern    char    MSG_kill_region[];
Xextern    char    MSG_yank[];
Xextern    char    MSG_down_window[];
Xextern    char    MSG_ins_toggle[];
Xextern    char    MSG_display_buffers[];
Xextern    char    MSG_quit[];
Xextern    char    MSG_exit_flush_all[];
Xextern    char    MSG_set_file_name[];
Xextern    char    MSG_file_insert[];
Xextern    char    MSG_buf_size_lock[];
Xextern    char    MSG_flush_all[];
Xextern    char    MSG_down_window[];
Xextern    char    MSG_up_window[];
Xextern    char    MSG_file_read[];
Xextern    char    MSG_file_save[];
Xextern    char    MSG_file_visit[];
Xextern    char    MSG_file_write[];
Xextern    char    MSG_swap_dot_and_mark[];
Xextern    char    MSG_shrink_window[];
Xextern    char    MSG_display_position[];
Xextern    char    MSG_start_macro[];
Xextern    char    MSG_end_macro[];
Xextern    char    MSG_help[];
Xextern    char    MSG_only_window[];
Xextern    char    MSG_split_window[];
Xextern    char    MSG_use_buffer[];
Xextern    char    MSG_spawn_cli[];
Xextern    char    MSG_execute_macro[];
Xextern    char    MSG_goto_line[];
Xextern    char    MSG_ins_unit[];
Xextern    char    MSG_kill_buffer[];
Xextern    char    MSG_load_bindings[];
Xextern    char    MSG_forw_window[];
Xextern    char    MSG_back_window[];
Xextern    char    MSG_view_file[];
Xextern    char    MSG_enlarge_window[];
Xextern    char    MSG_ascii_mode[];
Xextern    char    MSG_binary_mode[];
Xextern    char    MSG_buffer_name[];
Xextern    char    MSG_decimal_mode[];
Xextern    char    MSG_ebcdic_mode[];
Xextern    char    MSG_hex_mode[];
Xextern    char    MSG_back_del_unit[];
Xextern    char    MSG_octal_mode[];
Xextern    char    MSG_display_version[];
Xextern    char    MSG_unit_size1[];
Xextern    char    MSG_unit_size2[];
Xextern    char    MSG_unit_size4[];
Xextern    char    MSG_reposition_window[];
Xextern    char    MSG_set_mark[];
Xextern    char    MSG_goto_eob[];
Xextern    char    MSG_goto_bob[];
Xextern    char    MSG_next_buff[];
Xextern    char    MSG_prev_buff[];
Xextern    char    MSG_query_replace[];
Xextern    char    MSG_display_bindings[];
Xextern    char    MSG_auto_save[];
Xextern    char    MSG_back_unit[];
Xextern    char    MSG_compare[];
Xextern    char    MSG_forw_del_unit[];
Xextern    char    MSG_forw_unit[];
Xextern    char    MSG_link_windows[];
Xextern    char    MSG_print[];
Xextern    char    MSG_back_search[];
Xextern    char    MSG_forw_search[];
Xextern    char    MSG_back_page[];
Xextern    char    MSG_copy_region[];
Xextern    char    MSG_extended_command[];
Xextern    char    MSG_up_window[];
Xextern    char    MSG_search_again[];
Xextern    char    MSG_bind_to_key[];
Xextern    char    MSG_file_visit_split[];
Xextern    char    MSG_yank_buffer[];
Xextern    char    MSG_save_region[];
Xextern    char    MSG_use_buffer_split[];
Xextern    char    MSG_no_f_tb[];
X
X#include    "lintfunc.dec"
X#define SPECIAL 0x1F            /* Special keys         */
X
Xtypedef    struct  key_name_array 
X    {
X    int     key_code;
X    char    *func_name_str;
X    char    *key_name_str;
X    }   KEY_NAME_ARRAY; 
X#if MSDOS
Xextern  bool    wang_pc;
Xextern  bool    ibm_pc;
X#endif
X/*
X * The keyboard's special characters, those things that are prefixed with
X * a 0x1F, are placed into the keyboard tables as KCTRL || 0x80 || x, for some
X * x, i.e. they have both the control and 0x80 bits set, so they won't conflict
X * with anything else on the keyboard.
X */
X
X
X/*
X * Names for the keys with basic keycode
X * between KFIRST and KLAST (inclusive). This is used by
X * the key name routine in "kbd.c".
X */
X#if MSDOS
XKEY_NAME_ARRAY wang_keys[] =
X{
X    KCTRL | 0x80, MSG_bind_to_key, "Indent", 
X/*  KCTRL | 0x81, NULL, "Page", */
X    KCTRL | 0x82, MSG_reposition_window, "Center",
X/*  KCTRL | 0x83, NULL, "DecTab", */
X/*  KCTRL | 0x84, NULL, "Format", */
X/*  KCTRL | 0x85, NULL, "Merge", */
X/*  KCTRL | 0x86, NULL, "Note", */
X    KCTRL | 0x87, MSG_set_mark, "Stop",
X    KCTRL | 0x88, MSG_forw_search, "Search", 
X    KCTRL | 0x89, MSG_yank, "Replace",
X    KCTRL | 0x8A, MSG_copy_region, "Copy",
X    KCTRL | 0x8B, MSG_kill_region, "Move",
X    KCTRL | 0x8C, MSG_extended_command, "Command",
X    KCTRL | 0x8D, MSG_forw_window, "UpDown",
X/*  KCTRL | 0x8E, NULL, "BlankKey", */
X    KCTRL | 0x8F, MSG_goto_line, "GoTo",
X/*  KCTRL | 0x90, NULL, "Sh-Indent", */
X/*  KCTRL | 0x91, NULL, "Sh-Page", */
X/*  KCTRL | 0x92, NULL, "Sh-Center", */
X/*  KCTRL | 0x93, NULL, "Sh-DecTab", */
X/*  KCTRL | 0x94, NULL, "Sh-Format", */
X/*  KCTRL | 0x95, NULL, "Sh-Merge", */
X/*  KCTRL | 0x96, NULL, "Sh-Note", */
X/*  KCTRL | 0x97, NULL, "Sh-Stop", */
X    KCTRL | 0x98, MSG_search_again, "Sh-Search",
X    KCTRL | 0x99, MSG_query_replace, "Sh-Replace",
X/*  KCTRL | 0x9A, NULL, "Sh-Copy", */
X/*  KCTRL | 0x9B, NULL, "Sh-Move", */
X/*  KCTRL | 0x9C, NULL, "Sh-Command", */
X    KCTRL | 0x9D, MSG_split_window, "Sh-UpDown",
X/*  KCTRL | 0x9E, NULL, "Sh-BlankKey", */
X/*  KCTRL | 0x9F, NULL, "Sh-GoTo", */
X    KCTRL | 0xC0, MSG_back_line, "North",
X    KCTRL | 0xC1, MSG_forw_char, "East",
X    KCTRL | 0xC2, MSG_forw_line, "South",
X    KCTRL | 0xC3, MSG_back_char, "West",
X    KCTRL | 0xC4, MSG_byte_shift, "Home",
X/*  KCTRL | 0xC5, NULL, "Execute", */
X    KCTRL | 0xC6, MSG_ins_toggle, "Insert",
X    KCTRL | 0xC7, MSG_forw_del_char, "Delete",
X    KCTRL | 0xC8, MSG_back_page, "PrevPage",
X    KCTRL | 0xC9, MSG_forw_page, "NextPage",
X/*  KCTRL | 0xCB, NULL, "Erase", */
X/*  KCTRL | 0xCD, NULL, "BackTab", */
X/*  KCTRL | 0xD0, NULL, "Sh-North", */
X    KCTRL | 0xD1, MSG_forw_unit, "Sh-East",
X/*  KCTRL | 0xD2, NULL, "Sh-South", */
X    KCTRL | 0xD3, MSG_back_unit, "Sh-West",
X/*  KCTRL | 0xD4, NULL, "Sh-Home", */
X    KCTRL | 0xD5, MSG_execute_macro, "Sh-Execute",
X/*  KCTRL | 0xD6, NULL, "Sh-Insert", */
X    KCTRL | 0xD7, MSG_forw_del_unit, "Sh-Delete",
X    KCTRL | 0xD8, MSG_goto_bob, "Sh-PrevPage",
X    KCTRL | 0xD9, MSG_goto_eob, "Sh-NextPage",
X/*  KCTRL | 0xDB, NULL, "Sh-Erase", */
X/*  KCTRL | 0xDC, NULL, "Sh-Tab", */
X/*  KCTRL | 0xDD, NULL, "Sh-BackTab", */
X    KCTRL | 0xE0, MSG_abort, "Cancel",
X    KMETA | KCTRL | 0xE0, MSG_abort, "Cancel",
X    KCTLX | KCTRL | 0xE0, MSG_abort, "Ctl-X Cancel",
X    KCTRL | 0xE1, MSG_display_bindings, "Help",
X/*  KCTRL | 0xE2, NULL, "Glossary", */
X    KCTRL | 0xE3, MSG_print, "Print",
X    KCTRL | 0xF1, MSG_help, "Sh-Help",
X/*  KCTRL | 0xF2, NULL, "Sh-Glossary", */
X/*  KCTRL | 0xF3, NULL, "Sh-Print", */
X    0, NULL, NULL
X    };
X
XKEY_NAME_ARRAY  ibm_keys[] =
X    {
X    KCTLX | 0x80 | 0x3B, MSG_display_bindings, "F1",
X    KCTLX | 0x80 | 0x3C, MSG_set_mark, "F2",
X    KCTLX | 0x80 | 0x3D, MSG_forw_search, "F3",
X    KCTLX | 0x80 | 0x3E, MSG_search_again, "F4",
X    KCTLX | 0x80 | 0x3F, MSG_query_replace, "F5",
X    KCTLX | 0x80 | 0x40, MSG_yank, "F6",
X    KCTLX | 0x80 | 0x41, MSG_copy_region, "F7",
X    KCTLX | 0x80 | 0x42, MSG_kill_region, "F8",
X    KCTLX | 0x80 | 0x43, MSG_goto_line, "F9",
X    KCTLX | 0x80 | 0x44, MSG_abort, "F10",
X    KCTLX | 0x80 | 0x54, MSG_help, "Sh-F1",
X    KCTLX | 0x80 | 0x55, MSG_file_read, "Sh-F2",
X    KCTLX | 0x80 | 0x56, MSG_file_save, "Sh-F3",
X    KCTLX | 0x80 | 0x57, MSG_file_visit, "Sh-F4",
X    KCTLX | 0x80 | 0x58, MSG_file_write, "Sh-F5",
X    KCTLX | 0x80 | 0x59, MSG_flush_all, "Sh-F6",
X    KCTLX | 0x80 | 0x5A, MSG_set_file_name, "Sh-F7",
X    KCTLX | 0x80 | 0x5B, MSG_file_insert, "Sh-F8",
X    KCTLX | 0x80 | 0x5C, MSG_exit_flush_all, "Sh-F9",
X    KCTLX | 0x80 | 0x5D, MSG_quit, "Sh-F10",
X    KCTLX | 0x80 | 0x5E, MSG_display_buffers, "Ctl-F1",
X    KCTLX | 0x80 | 0x5F, MSG_use_buffer, "Ctl-F2",
X    KCTLX | 0x80 | 0x60, MSG_kill_buffer, "Ctl-F3",
X    KCTLX | 0x80 | 0x61, MSG_next_buff, "Ctl-F4",
X    KCTLX | 0x80 | 0x62, MSG_prev_buff, "Ctl-F5",
X    KCTLX | 0x80 | 0x63, MSG_yank_buffer, "Ctl-F6",
X    KCTLX | 0x80 | 0x64, MSG_set_file_name, "Ctl-F7",
X    KCTLX | 0x80 | 0x65, MSG_file_insert, "Ctl-F8",
X    KCTLX | 0x80 | 0x66, MSG_exit_flush_all, "Ctl-F9",
X    KCTLX | 0x80 | 0x67, MSG_quit, "Ctl-F10",
X    KCTLX | 0x80 | 0x48, MSG_back_line, "North",
X    KCTLX | 0x80 | 0x4D, MSG_forw_char, "East",
X    KCTLX | 0x80 | 0x74, MSG_forw_unit, "Ctl-East",
X    KCTLX | 0x80 | 0x50, MSG_forw_line, "South",
X    KCTLX | 0x80 | 0x4B, MSG_back_char, "West",
X    KCTLX | 0x80 | 0x73, MSG_back_unit, "Ctl-West",
X    KCTLX | 0x80 | 0x49, MSG_back_page, "PageDown",
X    KCTLX | 0x80 | 0x47, MSG_goto_bob, "Home",
X    KCTLX | 0x80 | 0x51, MSG_forw_page, "PageUp",
X    KCTLX | 0x80 | 0x4F, MSG_goto_eob, "End",
X    KCTLX | 0x80 | 0x52, MSG_ins_toggle, "Insert",
X    KCTLX | 0x80 | 0x53, MSG_forw_del_char, "Delete",
X    KCTLX | 0x80 | 0x76, MSG_forw_window, "Ctl-PageDown",
X    KCTLX | 0x80 | 0x84, MSG_back_window, "Ctl-PageUp",
X    KCTLX | 0x80 | 0x72, MSG_print, "Ctl-Print",
X    KCTLX | 0x80 | 0x0F, MSG_forw_unit, "Sh-Tab",
X    0, NULL, NULL
X    };
X#endif
X/*
X * Read in a key, doing the low level mapping
X * of ASCII code to 11 bit code.  This level deals with
X * mapping the special keys into their spots in the C1
X * control area.  The C0 controls go right through, and
X * get remapped by "getkey".
X */
Xstatic int  unkey = KRANDOM;    /* jam - for ungetkey */
Xvoid ungetkey (k)
X{
X    unkey = k;
X}
X
Xint     getkbd ()
X{
X    register int    c;
X
X    if (unkey == KRANDOM)       /* jam */
X        c = ttgetc ();
X    else
X        {
X        c = unkey;
X        unkey = KRANDOM;
X        }
X    if (c == SPECIAL)
X        {
X        c = ttgetc ();
X        if ((c == 0xCD) || (c == 0xDD))/* Backtab is meta */
X            return (METACH);
X        return (c | KCTRL);
X        }
X    if (c == 0)
X        {
X        c = ttgetc ();
X        return (c | 0x80 | KCTLX);
X        }
X    return (c);
X}
X
X
X/*
X * Terminal specific keymap initialization.
X * Attach the special keys to the appropriate built
X * in functions.
X * As is the case of all the keymap routines, errors
X * are very fatal.
X */
Xvoid ttykeymapinit ()
X{
XKEY_NAME_ARRAY  *ptr;
Xint     i;
Xchar    buf[60];
X#if MSDOS
X    if (wang_pc)
X        ptr = wang_keys;
X
X    if (ibm_pc)
X        ptr = ibm_keys;
X
X    if (!wang_pc && !ibm_pc)
X        return;
X
X    i = 0;
X    while (ptr -> key_code != 0)
X        {
X        if (ptr -> func_name_str != NULL)
X            keydup (ptr -> key_code, ptr -> func_name_str);
X        ptr++;
X        i++;
X        }
X    sprintf (buf, MSG_sp_key, i);
X    writ_echo (buf);
X#endif
X}
X/* 
X*   Search key name array for given key code.
X*   return pointer to key name.
X*/
Xchar    *keystrings (key)
Xint     key;
X    {
X#if MSDOS
X    KEY_NAME_ARRAY  *ptr;
X    
X    if (wang_pc)
X        ptr = wang_keys;
X
X    if (ibm_pc)
X        ptr = ibm_keys;
X
X    if (!wang_pc && !ibm_pc)
X        return(NULL);
X
X    while (ptr -> key_code != 0)
X        {
X        if (key == ptr -> key_code)
X            {
X            return (ptr -> key_name_str);
X            }
X        ptr++;
X        }
X#endif
X    return (NULL);
X    }
END_OF_FILE
if test 11412 -ne `wc -c <'ttykbd.c'`; then
    echo shar: \"'ttykbd.c'\" unpacked with wrong size!
fi
chmod +x 'ttykbd.c'
# end of 'ttykbd.c'
fi
if test -f 'window.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'window.c'\"
else
echo shar: Extracting \"'window.c'\" \(12083 characters\)
sed "s/^X//" >'window.c' <<'END_OF_FILE'
X/*
X*       Window handling.
X*/
X#include    "def.h"
X
Xchar    mvupwind ();
Xbool    shrinkwind ();
X
Xextern    char    MSG_no_splt[];
Xextern    char    MSG_cnt_al_w[];
Xextern    char    MSG_one_w[];
Xextern    char    MSG_imp_chg[];
X
X#include    "lintfunc.dec"
X/*
X* Reposition the window so as to center on the dot.
X*/
Xbool reposition ()
X{
X    long    l_val;
X
X    l_val = DOT_POS(curwp) - (curwp -> w_ntrows * R_BYTES(curwp) / 2);
X    move_ptr (curwp, l_val, FALSE, TRUE, FALSE);
X    curwp -> w_flag |= WFHARD;
X    return (TRUE);
X}
X
X/*
X* The command make the next
X* window (next => down the screen)
X* the current window. There are no real
X* errors, although the command does
X* nothing if there is only 1 window on
X* the screen.
X*/
Xbool nextwind ()
X{
X
X    register    WINDOW * wp;
X
X    if ((wp = curwp -> w_wndp) == NULL)
X        wp = wheadp;
X    curwp = wp;
X    curbp = wp -> w_bufp;
X    return (TRUE);
X}
X
X
X/*
X* This command makes the previous
X* window (previous => up the screen) the
X* current window. There arn't any errors,
X* although the command does not do a lot
X* if there is 1 window.
X*/
Xbool prevwind ()
X{
X
X    register    WINDOW * wp1;
X    register    WINDOW * wp2;
X
X    wp1 = wheadp;
X    wp2 = curwp;
X    if (wp1 == wp2)
X        wp2 = NULL;
X    while (wp1 -> w_wndp != wp2)
X        wp1 = wp1 -> w_wndp;
X    curwp = wp1;
X    curbp = wp1 -> w_bufp;
X    return (TRUE);
X}
X
X
X/*
X* This command moves the current
X* window down by "arg" lines. Recompute
X* the top line in the window. The move up and
X* move down code is almost completely the same;
X* most of the work has to do with reframing the
X* window, and picking a new dot. We share the
X* code by having "move down" just be an interface
X* to "move up".
X*/
Xchar    mvdnwind (f, n, k)
Xregister int    n;
X{
X    return (mvupwind (f, -n, KRANDOM));
X}
X
X
X/*
X* Move the current window up by "arg"
X* lines. Recompute the new top line of the window.
X* Look to see if "." is still on the screen. If it is,
X* you win. If it isn't, then move "." to center it
X* in the new framing of the window (this command does
X* not really move "."; it moves the frame).
X*/
Xchar    mvupwind (f, n, k)
X    int    n;
X{
X    A32   l_val, l_bytes;
X
X    l_bytes = (A32)R_BYTES(curwp);     /* number of bytes in a row */
X    l_val = n * l_bytes;     /* number of bytes to move */
X    move_ptr (curwp, l_val, FALSE, TRUE, TRUE);  /* move window */
X
X    /* check that dot is in window */
X    while (DOT_POS(curwp) < WIND_POS(curwp))
X    {
X        /* dot is before the first window line */
X        move_ptr (curwp, l_bytes, TRUE, TRUE, TRUE);
X    }
X    while (DOT_POS (curwp) >=
X             ((l_bytes * curwp -> w_ntrows) + WIND_POS(curwp)))
X    {
X        /* dot is after the last window line */
X        move_ptr (curwp, -l_bytes, TRUE, TRUE, TRUE);
X    }
X    curwp -> w_flag |= WFHARD;
X    return (TRUE);
X}
X
X
X/*
X* This command makes the current
X* window the only window on the screen.
X* Try to set the framing
X* so that "." does not have to move on
X* the display. Some care has to be taken
X* to keep the values of dot and mark
X* in the buffer structures right if the
X* distruction of a window makes a buffer
X* become undisplayed.
X*/
Xchar    onlywind ()
X{
X
X    register    WINDOW * wp;
X    register    LINE * lp;
X    register int    i;
X
X    while (wheadp != curwp)
X        {
X
X        wp = wheadp;
X        wheadp = wp -> w_wndp;
X        if (--wp -> w_bufp -> b_nwnd == 0)
X            {
X
X            wp -> w_bufp -> b_dotp = wp -> w_dotp;
X            wp -> w_bufp -> b_doto = wp -> w_doto;
X            wp -> w_bufp -> b_markp = wp -> w_markp;
X            wp -> w_bufp -> b_marko = wp -> w_marko;
X            }
X
X        free ((char *) wp);
X        }
X
X    while (curwp -> w_wndp != NULL)
X        {
X
X        wp = curwp -> w_wndp;
X        curwp -> w_wndp = wp -> w_wndp;
X        if (--wp -> w_bufp -> b_nwnd == 0)
X            {
X
X            wp -> w_bufp -> b_dotp = wp -> w_dotp;
X            wp -> w_bufp -> b_doto = wp -> w_doto;
X            wp -> w_bufp -> b_markp = wp -> w_markp;
X            wp -> w_bufp -> b_marko = wp -> w_marko;
X            }
X
X        free ((char *) wp);
X        }
X
X    lp = curwp -> w_linep;
X    i = curwp -> w_toprow;
X    while (i != 0 && lback (lp) != curbp -> b_linep)
X        {
X
X        --i;
X        lp = lback (lp);
X        }
X
X    curwp -> w_toprow = 0;
X    curwp -> w_ntrows = nrow - 2;/* 2 = mode, echo.  */
X    curwp -> w_linep = lp;
X    curwp -> w_flag |= WFMODE | WFHARD;
X    return (TRUE);
X}
X
X/*
X * Delete the current window, placing its space in the window above,
X * or, if it is the top window, the window below. Bound to C-X 0.
X */
X
Xdelwind()
X
X{
X	register WINDOW *wp;	/* window to recieve deleted space */
X	register WINDOW *lwp;	/* ptr window before curwp */
X	register int target;	/* target line to search for */
X
X	/* if there is only one window, don't delete it */
X	if (wheadp->w_wndp == NULL) {
X		return(FALSE);
X	}
X
X	/* find window before curwp in linked list */
X	wp = wheadp;
X	lwp = NULL;
X	while (wp != NULL) {
X		if (wp == curwp)
X			break;
X		lwp = wp;
X		wp = wp->w_wndp;
X	}
X
X	/* find recieving window and give up our space */
X	wp = wheadp;
X	if (curwp->w_toprow == 0) {
X		/* find the next window down */
X		target = curwp->w_ntrows + 1;
X		while (wp != NULL) {
X			if (wp->w_toprow == target)
X				break;
X			wp = wp->w_wndp;
X		}
X		if (wp == NULL)
X			return(FALSE);
X		wp->w_toprow = 0;
X		wp->w_ntrows += target;
X	} else {
X		/* find the next window up */
X		target = curwp->w_toprow - 1;
X		while (wp != NULL) {
X			if ((wp->w_toprow + wp->w_ntrows) == target)
X				break;
X			wp = wp->w_wndp;
X		}
X		if (wp == NULL)
X			return(FALSE);
X		wp->w_ntrows += 1 + curwp->w_ntrows;
X	}
X
X	/* get rid of the current window */
X	if (--curwp->w_bufp->b_nwnd == 0) {
X		curwp->w_bufp->b_dotp = curwp->w_dotp;
X		curwp->w_bufp->b_doto = curwp->w_doto;
X		curwp->w_bufp->b_markp = curwp->w_markp;
X		curwp->w_bufp->b_marko = curwp->w_marko;
X	}
X	if (lwp == NULL)
X		wheadp = curwp->w_wndp;
X	else
X		lwp->w_wndp = curwp->w_wndp;
X	free((char *)curwp);
X	curwp = wp;
X    wp -> w_flag |= WFMODE | WFHARD;
X	curbp = wp->w_bufp;
X	return(TRUE);
X}
X
X/*
X* Split the current window. A window
X* smaller than 3 lines cannot be split.
X* The only other error that is possible is
X* a "malloc" failure allocating the structure
X* for the new window.
X*/
Xbool splitwind ()
X{
X
X    register    WINDOW * wp;
X    register int    ntru;
X    register int    ntrl;
X    register int    ntrd;
X    register    WINDOW * wp1;
X    register    WINDOW * wp2;
X    char    buf[80], buf1[40];
X
X    if (curwp -> w_ntrows < 3)
X        {
X        sprintf (buf1, MSG_no_splt, R_BYTE_FMT(curwp));
X        sprintf (buf, buf1, curwp -> w_ntrows);
X        writ_echo (buf);
X        return (FALSE);
X        }
X
X    if ((wp = (WINDOW *) malloc (sizeof (WINDOW))) == NULL)
X        {
X
X        writ_echo (MSG_cnt_al_w);
X        return (FALSE);
X        }
X
X    ++curbp -> b_nwnd;          /* Displayed twice.  */
X    wp -> w_bufp = curbp;
X    wp -> w_dotp = curwp -> w_dotp;
X    wp -> w_doto = curwp -> w_doto;
X    wp -> w_unit_offset = curwp -> w_unit_offset;
X    wp -> w_markp = curwp -> w_markp;
X    wp -> w_marko = curwp -> w_marko;
X    wp -> w_flag = 0;
X    wp -> w_disp_shift = curwp -> w_disp_shift;
X    wp -> w_intel_mode = curwp -> w_intel_mode;
X    wp -> w_fmt_ptr = curwp -> w_fmt_ptr;
X    ntru = (curwp -> w_ntrows - 1) / 2;/* Upper size         */
X    ntrl = (curwp -> w_ntrows - 1) - ntru;/* Lower size      */
X
X    if (ntrd <= get_currow (curwp))
X        {
X    /* Old is upper window.      */
X        curwp -> w_ntrows = ntru;
X        wp -> w_wndp = curwp -> w_wndp;
X        curwp -> w_wndp = wp;
X        wp -> w_toprow = curwp -> w_toprow + ntru + 1;
X        wp -> w_ntrows = ntrl;
X        }
X    else
X        {
X    /* Old is lower window       */
X        wp1 = NULL;
X        wp2 = wheadp;
X        while (wp2 != curwp)
X            {
X            wp1 = wp2;
X            wp2 = wp2 -> w_wndp;
X            }
X
X        if (wp1 == NULL)
X            wheadp = wp;
X        else
X            wp1 -> w_wndp = wp;
X        wp -> w_wndp = curwp;
X        wp -> w_toprow = curwp -> w_toprow;
X        wp -> w_ntrows = ntru;
X        ++ntru;                 /* Mode line.        */
X        curwp -> w_toprow += ntru;
X        curwp -> w_ntrows = ntrl;
X        }
X
X    wind_on_dot (curwp);        /* put window on the dot */
X    wp -> w_loff = curwp -> w_loff;/* do the same for the new window */
X    wp -> w_linep = curwp -> w_linep;
X    curwp -> w_flag |= WFMODE | WFHARD;
X    wp -> w_flag |= WFMODE | WFHARD;
X    return (TRUE);
X}
X
X
X/*
X* Enlarge the current window.
X* Find the window that loses space. Make
X* sure it is big enough. If so, hack the window
X* descriptions, and ask redisplay to do all the
X* hard work. You don't just set "force reframe"
X* because dot would move.
X*/
Xbool enlargewind (f, n, k)
X{
X    register    WINDOW * adjwp;
X    register    LINE * lp;
X    register int    i;
X
X    if (n < 0)
X        return (shrinkwind (f, -n, KRANDOM));
X    if (wheadp -> w_wndp == NULL)
X        {
X
X        writ_echo (MSG_one_w);
X        return (FALSE);
X        }
X
X    if ((adjwp = curwp -> w_wndp) == NULL)
X        {
X        adjwp = wheadp;
X        while (adjwp -> w_wndp != curwp)
X            adjwp = adjwp -> w_wndp;
X        }
X
X    if (adjwp -> w_ntrows <= n)
X        {
X        writ_echo (MSG_imp_chg);
X        return (FALSE);
X        }
X
X    if (curwp -> w_wndp == adjwp)
X        {
X    /* Shrink below.     */
X        lp = adjwp -> w_linep;
X        for (i = 0; i < n && lp != adjwp -> w_bufp -> b_linep; ++i)
X            lp = lforw (lp);
X        adjwp -> w_linep = lp;
X        adjwp -> w_toprow += n;
X        }
X    else
X        {
X    /* Shrink above.     */
X        lp = curwp -> w_linep;
X        for (i = 0; i < n && lback (lp) != curbp -> b_linep; ++i)
X            lp = lback (lp);
X        curwp -> w_linep = lp;
X        curwp -> w_toprow -= n;
X        }
X
X    curwp -> w_ntrows += n;
X    adjwp -> w_ntrows -= n;
X    curwp -> w_flag |= WFMODE | WFHARD;
X    adjwp -> w_flag |= WFMODE | WFHARD;
X    return (TRUE);
X}
X
X
X/*
X* Shrink the current window.
X* Find the window that gains space. Hack at
X* the window descriptions. Ask the redisplay to
X* do all the hard work.
X*/
Xbool shrinkwind (f, n, k)
X{
X    register    WINDOW * adjwp;
X    register    LINE * lp;
X    register int    i;
X
X    if (n < 0)
X        return (enlargewind (f, -n, KRANDOM));
X    if (wheadp -> w_wndp == NULL)
X        {
X        writ_echo (MSG_one_w);
X        return (FALSE);
X        }
X
X    if ((adjwp = curwp -> w_wndp) == NULL)
X        {
X        adjwp = wheadp;
X        while (adjwp -> w_wndp != curwp)
X            adjwp = adjwp -> w_wndp;
X        }
X
X    if (curwp -> w_ntrows <= n)
X        {
X        writ_echo (MSG_imp_chg);
X        return (FALSE);
X        }
X
X    if (curwp -> w_wndp == adjwp)
X        {
X    /* Grow below.       */
X        lp = adjwp -> w_linep;
X        for (i = 0; i < n && lback (lp) != adjwp -> w_bufp -> b_linep; ++i)
X            lp = lback (lp);
X        adjwp -> w_linep = lp;
X        adjwp -> w_toprow -= n;
X        }
X    else
X        {
X    /* Grow above.       */
X        lp = curwp -> w_linep;
X        for (i = 0; i < n && lp != curbp -> b_linep; ++i)
X            lp = lforw (lp);
X        curwp -> w_linep = lp;
X        curwp -> w_toprow += n;
X        }
X
X    curwp -> w_ntrows -= n;
X    adjwp -> w_ntrows += n;
X    curwp -> w_flag |= WFMODE | WFHARD;
X    adjwp -> w_flag |= WFMODE | WFHARD;
X    return (TRUE);
X}
X
X
X/*
X* Pick a window for a pop-up.
X* Split the screen if there is only
X* one window. Pick the uppermost window that
X* isn't the current window. An LRU algorithm
X* might be better. Return a pointer, or
X* NULL on error.
X*/
XWINDOW * wpopup ()
X{
X
X    register    WINDOW * wp;
X
X    if (wheadp -> w_wndp == NULL
X            && splitwind () == FALSE)
X        return (NULL);
X    wp = wheadp;                /* Find window to use    */
X    while (wp != NULL && wp == curwp)
X        wp = wp -> w_wndp;
X    return (wp);
X}
X
X
X/*
X* Refresh the display. 
X* In the normal case the
X* call to "update" in "main.c" refreshes the screen,
X* and all of the windows need not be recomputed.
X*/
Xbool refresh ()
X{
X    sgarbf = TRUE;
X    return (TRUE);
X}
END_OF_FILE
if test 12083 -ne `wc -c <'window.c'`; then
    echo shar: \"'window.c'\" unpacked with wrong size!
fi
chmod +x 'window.c'
# end of 'window.c'
fi
echo shar: End of archive 2 \(of 10\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0


-- 
>>>>>>>>>>>>>>>> Peter Reilley ..... pvr@wang.com <<<<<<<<<<<<<<<<<<<<<<<
                     Well, that about says it.

pvr@wang.com (Peter Reilley) (06/06/91)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 3 (of 10)."
# Contents:  basic.c extend.c main.c
# Wrapped by pvr@elf on Thu Mar 14 08:16:46 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'basic.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'basic.c'\"
else
echo shar: Extracting \"'basic.c'\" \(13944 characters\)
sed "s/^X//" >'basic.c' <<'END_OF_FILE'
X/*
X*      Basic cursor motion commands.
X* The routines in this file are the basic
X* command functions for moving the cursor around on
X* the screen, setting mark, and swapping dot with
X* mark. Only moves between lines, which might make the
X* current buffer framing bad, are hard.
X*/
X
X#include    "def.h"
X
Xbool    move_ptr ();
Xbool    forwchar ();
Xbool    wind_on_dot ();
Xbool    backline ();
X
Xextern    char    MSG_mark_set[];
Xextern    char    MSG_no_mark[];
Xextern    char    MSG_go_b_n[];
Xextern    char    MSG_bad_num[];
X#if RUNCHK
Xextern    char    ERR_bas_1[];
X#endif
Xextern    char    MSG_lX[];
Xextern    char    MSG_lO[];
Xextern    char    MSG_lD[];
X
X#include    "lintfunc.dec"
X
Xextern  bool    rplc_mode;
X
X/*  pvr
X* Move cursor backwards. Do the
X* right thing if the count is less than
X* 0. Error if you try to move back from
X* the beginning of the buffer.
X*/
Xbool backchar (f, n, k)
Xregister int    n;
X{
X    if (n < 0)
X        return (forwchar (f, -n, KRANDOM));
X
X    while (n--)
X        {
X        if (curwp -> w_unit_offset == 0)
X            {
X            if (!move_ptr (curwp,  -(long)R_B_PER_U(curwp),
X                    TRUE, TRUE, TRUE))
X                return (FALSE);
X
X        /* step to previous unit */
X            curwp -> w_unit_offset = R_CHR_PER_U(curwp) - 1;
X
X        /* if before first line in window then move window */
X            wind_on_dot (curwp);
X            }
X        else
X            curwp -> w_unit_offset--;
X        }
X    curwp -> w_flag |= WFMODE;  /* update mode line */
X    return (TRUE);
X}
X
X/*  pvr
X* Move cursor forwards. Do the
X* right thing if the count is less than
X* 0. Error if you try to move forward
X* from the end of the buffer.
X*/
Xbool forwchar (f, n, k)
Xregister int    n;
X{
X    if (n < 0)
X        return (backchar (f, -n, KRANDOM));
X
X    curwp -> w_flag |= WFMODE;  /* update mode line */
X    while (n--)
X        {
X        if (curwp -> w_unit_offset >= (R_CHR_PER_U(curwp) - 1))
X            {
X        /* move to the mext unit */
X            curwp -> w_unit_offset = 0;
X
X            if (!move_ptr (curwp,  (long)R_B_PER_U(curwp),
X                    TRUE, TRUE, TRUE))
X                {
X            /* I am at the the end of the buffer */
X                return (FALSE);
X                }
X
X        /* if after the last line in window then move window */
X            wind_on_dot (curwp);
X            }
X        else   /* if at last byte of buffer then do not step  */
X            if (DOT_POS(curwp) < BUF_SIZE(curwp))
X                curwp -> w_unit_offset++;/* step within unit */
X        }
X    return (TRUE);
X}
X
X/*  pvr
X*   This function moves the specified pointer by the ammount specified
X*   in 'len'.   Move the dot pointer is 'dot' is true, else move
X*   the window pointer.  Do the fix up if 'fix' is TRUE.
X*   This is a relative move if 'rel' is TRUE, else it is an
X*   absolute move.
X*/
X
Xbool    move_ptr (wp, len, dot, fix, rel)
XWINDOW  *wp;
Xlong    len;
Xbool    dot, fix, rel;  
X{
X    A32     cur_pos, dest_pos, fix_val, last_pos;
X    long    rel_pos;
X    A32     last_fixed_pos, align;
X    LINE    **line, *line_guess;
X    int     *l_off;
X    char    shift;
X    bool    no_limit;
X
X    no_limit = TRUE;
X    if (dot)
X        {                       /* move dot position */
X        l_off = &wp -> w_doto;
X        line = &wp -> w_dotp;
X        align = R_SIZE(wp);  /* bytes -1 in a unit */
X        }
X    else
X        {                       /* move window position */
X        l_off = &wp -> w_loff;
X        line = &wp -> w_linep;
X        align = R_ALIGN(wp) - 1; /* interval of bytes to align window */
X        }
X
X    /* get the current position in the buffer */
X    cur_pos = (*line) -> l_file_offset + *l_off;
X
X    if (rel)
X        {
X        rel_pos = len;
X        dest_pos = len + cur_pos;   /* destination position */
X        }
X    else
X        {
X        rel_pos = len - cur_pos;   /* relative move amount */
X        dest_pos = len;   /* destination position */
X        }
X    if (fix)
X        {
X        shift = wp -> w_disp_shift;
X
X        /* limit at begining */
X        if (dest_pos < shift)
X            {
X            rel_pos = shift - cur_pos;
X            no_limit = FALSE;
X            }
X        else
X            {
X            /* calculate fixed up destination position */
X            fix_val = dest_pos &= ~align;
X            fix_val += shift;
X
X            /* calculate the last position in the buffer */
X            last_pos = BUF_SIZE(wp);
X            if (last_pos < (last_fixed_pos = (last_pos & ~align) + shift))
X                last_pos = last_fixed_pos - align - 1;
X
X            /* if we are going to limit at the end of the buffer */
X            if (last_pos < fix_val)
X                {
X                fix_val = last_pos;
X                no_limit = FALSE;
X                }
X            rel_pos = fix_val - cur_pos; 
X            }
X        }
X    while (TRUE)
X        {
X        if (rel_pos < 0)       /* move  backward through buffer */
X            {
X            /* current line? */
X            if (*l_off + rel_pos >= 0)
X                {
X                *l_off += (short) rel_pos;
X                return (no_limit);
X                }
X        /* are we at the first line */
X            if ((*line) -> l_bp -> l_size != 0)
X                {               /* no, so step back */
X                rel_pos += *l_off;
X                (*line) = (*line) -> l_bp;/* move back one line */
X                *l_off = (*line) -> l_used;
X                }
X            else
X                {               /* yes, limit at the begining */
X                *l_off = 0;
X                return (FALSE);
X                }
X            }
X        else                    /* move forward through buffer */
X            {
X        /* is in current line? */
X            if (((A32)(*l_off) + rel_pos) < ((A32)((*line) -> l_used)))
X                {
X                *l_off += (short) rel_pos;
X                return (no_limit);
X                }
X            if ((*line) -> l_fp -> l_size != 0)
X                {
X                rel_pos -= (*line) -> l_used - *l_off;
X                *l_off = 0;
X                (*line) = (*line) -> l_fp;/* move forward one line */
X                }
X            else
X                {
X                *l_off = (*line) -> l_used;/* at last line so limit it */
X                return (FALSE);
X                }
X            }
X        }
X}
X
X/*  pvr
X*   Move the window so that the dot is within it's
X*   area.   Return TRUE if window was moved.
X*/
X
Xbool wind_on_dot (wp)
X
XWINDOW * wp;
X{
X    long    diff, incr;
X    A32     d_offs, w_start, bytes, align;
X
X /* number of bytes in a row */
X    bytes = R_BYTES(wp);
X /* number of bytes to align on */
X    align = R_ALIGN(wp);
X /* offset of window from start of the buffer */
X    w_start = WIND_POS(wp);
X /* offset of dot from start of the buffer */
X    d_offs = DOT_POS(wp);
X    /* calculate the amount to move that is 1/3 of the window */    
X    incr = bytes * wp -> w_ntrows / 3;
X /* if dot is before first line in window */
X    if ((diff = (d_offs - w_start)) < 0)/* diff used later */
X        {
X        move_ptr (wp, diff - incr, FALSE, TRUE, TRUE);
X        wp -> w_flag |= WFHARD;
X        return (TRUE);
X        }
X /* if dot is after the last line in window */
X    if (0 < (diff -= (wp -> w_ntrows * bytes - 1)))
X        {
X        if (align != 1)
X            diff = (diff & ~(align - 1)) + align;
X        move_ptr (wp, diff + incr, FALSE, TRUE, TRUE);
X        wp -> w_flag |= WFHARD;
X        return (TRUE);
X        }
X /* is window aligned? */
X    if (w_start != ((w_start & ~(align - 1)) + wp -> w_disp_shift))
X        {                       /* if no then move into alignment */
X        move_ptr (wp, 0L, FALSE, TRUE, TRUE);
X        wp -> w_flag |= WFHARD;
X        return (TRUE);
X        }
X    return (FALSE);
X}
X
X/*  pvr
X* Go to the beginning of the
X* buffer. Setting WFHARD is conservative,
X* but almost always the case.
X*/
Xbool gotobob ()
X{
X    move_ptr (curwp, 0L, TRUE, TRUE, FALSE);    /* move dot */
X    move_ptr (curwp, 0L, FALSE, TRUE, FALSE);   /* move window */
X    curwp -> w_unit_offset = 0;
X    curwp -> w_flag |= WFHARD;
X    return (TRUE);
X}
X
X
X/*  pvr
X* Go to the end of the buffer.
X* Setting WFHARD is conservative, but
X* almost always the case.
X* Dot is one byte past the end of the buffer.
X*/
Xbool gotoeob ()
X{
X    long    f_off;
X    long    index;
X
X    move_ptr (curwp, BUF_SIZE(curwp), TRUE, TRUE, FALSE);  /* move dot */
X    curwp -> w_unit_offset = 0;
X    wind_on_dot (curwp);
X    return (TRUE);
X}
X
X
X/*  pvr
X* Move forward by full lines.
X* If the number of lines to move is less
X* than zero, call the backward line function to
X* actually do it. The last command controls how
X* the goal column is set.
X*/
Xbool forwline (f, n, k)
X{
X    if (n < 0)
X        return (backline (f, -n, KRANDOM));
X
X    if (rplc_mode)
X    {
X        next_pat ();
X    }
X    else
X    {
X     /* move dot */
X        if (!move_ptr (curwp,  (long)R_BYTES(curwp) * n,
X                 TRUE, TRUE, TRUE))
X            curwp -> w_unit_offset = 0;
X        wind_on_dot (curwp);
X        curwp -> w_flag |= WFMODE;  /* update mode line */
X    }
X    return (TRUE);
X}
X
X
X/*  pvr
X* This function is like "forwline", but
X* goes backwards. The scheme is exactly the same.
X* Check for arguments that are less than zero and
X* call your alternate. Figure out the new line and
X* call "movedot" to perform the motion.
X*/
Xbool backline (f, n, k)
X{
X    if (n < 0)
X        return (forwline (f, -n, KRANDOM));
X
X    if (rplc_mode)
X    {
X        next_pat ();
X    }
X    else
X    {
X        if (!move_ptr (curwp,  -((long)(R_BYTES(curwp) * n)),
X                 TRUE, TRUE, TRUE))
X            curwp -> w_unit_offset = 0;
X
X     /* is dot before the top of window? */
X        wind_on_dot (curwp);
X        curwp -> w_flag |= WFMODE;  /* update mode line */
X    }   
X    return (TRUE);
X}
X
X/*  pvr
X* Scroll forward by a specified number
X* of lines, or by a full page if no argument.
X* (KRW) Added cursor (dot) weighting to force cursor
X*       to same position on new page.
X*/
Xbool forwpage (f, n, k)
Xregister int    n;
X{
X    long    mov_lines;
X
X    if (rplc_mode)
X        next_pat ();
X    else
X    {
X        if (curwp -> w_ntrows <= 2)
X            mov_lines = 2;
X        else
X            mov_lines = curwp -> w_ntrows - 2;
X
X     /* check if last line is already displayed */
X        if (WIND_POS(curwp) + (R_BYTES(curwp) * curwp -> w_ntrows) <
X                curwp -> w_bufp -> b_linep -> l_bp -> l_file_offset +
X                curwp -> w_bufp -> b_linep -> l_bp -> l_used)
X            {
X            move_ptr (curwp, (long)(R_BYTES(curwp) * mov_lines),
X                 FALSE, TRUE, TRUE);
X            }
X     /* move dot by same amount */
X        if (!move_ptr (curwp, (long)(R_BYTES(curwp) * mov_lines),
X                 TRUE, TRUE, TRUE))
X            curwp -> w_unit_offset = 0;
X
X        curwp -> w_flag |= WFHARD;
X    }
X    return (TRUE);
X}
X
X
X/*  pvr
X* This command is like "forwpage",
X* but it goes backwards. 
X*/
Xbool backpage (f, n, k)
Xregister int    n;
X{
X    long    mov_lines;
X
X    if (rplc_mode)
X        next_pat ();
X    else
X    {
X        if (curwp -> w_ntrows <= 2)
X            mov_lines = 2;
X        else
X            mov_lines = curwp -> w_ntrows - 2;
X
X     /* move window */
X        move_ptr (curwp, -(long)(R_BYTES(curwp) * mov_lines),
X                 FALSE, TRUE, TRUE);
X     /* move dot by same amount */
X        if (!move_ptr (curwp, -(long)(R_BYTES(curwp) * mov_lines),
X                 TRUE, TRUE, TRUE))
X            curwp -> w_unit_offset = 0;
X
X        curwp -> w_flag |= WFHARD;
X    }
X    return (TRUE);
X}
X
X
X/*
X* Set the mark in the current window
X* to the value of dot. A message is written to
X* the echo line unless we are running in a keyboard
X* macro, when it would be silly.
X*/
Xbool setmark ()
X{
X
X    if (curbp == blistp)        /* jam - hack to do goto/kill */
X        pickone ();
X    else
X        {
X        curwp -> w_markp = curwp -> w_dotp;
X        curwp -> w_marko = curwp -> w_doto;
X        if (kbdmop == NULL)
X            {
X            writ_echo (MSG_mark_set);
X            }
X        }
X    return (TRUE);
X}
X
X
X/*  pvr
X* Swap the values of "dot" and "mark" in
X* the current window. This is pretty easy, because
X* all of the hard work gets done by the standard routine
X* that moves the mark about. The only possible
X* error is "no mark".
X*/
Xbool swapmark ()
X{
X    register short  odoto;
X    register    LINE * odotp;
X
X    if (curwp -> w_markp == NULL)
X        {
X        writ_echo (MSG_no_mark);
X        return (FALSE);
X        }
X
X    odotp = curwp -> w_dotp;
X    curwp -> w_dotp = curwp -> w_markp;
X    curwp -> w_markp = odotp;
X    odoto = curwp -> w_doto;
X    curwp -> w_doto = curwp -> w_marko;
X    curwp -> w_marko = odoto;
X    wind_on_dot (curwp);
X    curwp -> w_flag |= WFMODE;  /* update mode line */
X    return (TRUE);
X}
X
X/*  pvr
X* Go to a specific byte position in buffer.
X* If an argument is present, then
X* it is the byte number, else prompt for a byte number
X* to use.
X*/
Xbool gotoline (f, n, k)
X{
X    A32      index;
X    register int    s;
X    char    buf[32];
X
X    if (f == FALSE)
X        {
X
X        if ((s = ereply (MSG_go_b_n, buf, sizeof (buf), 0) != TRUE))
X            return (s);
X        switch (R_TYPE(curwp))
X            {
X            case TEXT: 
X            case ASCII: 
X            case EBCDIC: 
X            case BINARY: 
X            case HEX: 
X                sscanf (buf, MSG_lX, &index);
X                break;
X            case OCTAL: 
X                sscanf (buf, MSG_lO, &index);
X                break;
X            case DECIMAL: 
X                sscanf (buf, MSG_lD, &index);
X                break;
X#if RUNCHK
X            default:
X                writ_echo (ERR_bas_1);
X                break;
X#endif
X            }
X        }
X
X    if (n <= 0)
X        {
X        writ_echo (MSG_bad_num);
X        return (FALSE);
X        }
X
X    move_ptr (curwp, index, TRUE, TRUE, FALSE);
X    curwp -> w_unit_offset = 0;
X
X    curwp -> w_flag |= WFMODE;  /* update mode line */
X
X    wind_on_dot (curwp);
X    return (TRUE);
X}
X
END_OF_FILE
if test 13944 -ne `wc -c <'basic.c'`; then
    echo shar: \"'basic.c'\" unpacked with wrong size!
fi
chmod +x 'basic.c'
# end of 'basic.c'
fi
if test -f 'extend.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'extend.c'\"
else
echo shar: Extracting \"'extend.c'\" \(12209 characters\)
sed "s/^X//" >'extend.c' <<'END_OF_FILE'
X/*
X*   Extended (M-X) commands.
X*/
X#include    "def.h"
X
Xextern    char    MSG_not_now[];
Xextern    char    MSG_func[];
Xextern    char    MSG_unk_func[];
Xextern    char    MSG_cmd_t_ex[];
Xextern    char    MSG_unk_ext[];
Xextern    char    MSG_d_b[];
Xextern    char    MSG_unbd[];
Xextern    char    MSG_bnd_to[];
Xextern    char    MSG_ins_self[];
Xextern    char    MSG_bnd_file[];
Xextern    char    MSG_bld_wall[];
Xextern    char    MSG_wall_head[];
Xextern    char    MSG_beavrc[];
Xextern    char    MSG_null[];
X
X#include    "lintfunc.dec"
X#ifdef CUSTOMIZE 
X
Xchar *flook();
X
Xstatic char *bindnm =
X{0
X};                              /* file name for customized key bindings */
X#endif 
X
X/*
X* This function modifies the keyboard
X* binding table, by adjusting the entries in the
X* big "bindings" array. Most of the grief deals with the
X* prompting for additional arguments. This code does not
X* work right if there is a keyboard macro floating around.
X* Should be fixed.
X*/
Xbool bindtokey ()
X{
X
X    register int    s;
X    register char  *cp;
X    register    SYMBOL * sp;
X    register int    c;
X    char    xname[NXNAME];
X#ifdef CUSTOMIZE
X    char    xname2[NXNAME];
X    FILE * bindf;
X#endif 
X
X    if (kbdmip != NULL || kbdmop != NULL)
X        {
X        writ_echo (MSG_not_now);
X        return (FALSE);
X        }
X
X    if ((s = eread (MSG_func, xname, NXNAME, EFAUTO, NULL)) != TRUE)
X        return (s);
X    if ((sp = symlookup (xname)) == NULL)
X        {
X        writ_echo (MSG_unk_func);
X        return (FALSE);
X        }
X
X#ifdef CUSTOMIZE
X    strcpy (xname2, xname);
X#endif 
X    eputc (' ');
X    eputc ('K');
X    eputc ('e');
X    eputc ('y');
X    eputc (':');
X    eputc (' ');
X    ttflush ();
X    c = getkey ();              /* Read key.        */
X    keyname (xname, c);         /* Display keyname. */
X    eputs (xname);
X    ttflush ();
X    if (binding[c] != NULL)     /* Unbind old, and  */
X        --binding[c] -> s_nkey;
X    binding[c] = sp;            /* rebind new.      */
X    ++sp -> s_nkey;
X    sp -> s_modify |= SBOUND;	/* flag as altered key binding */
X
X    return (TRUE);
X}
X
X
X/*
X* Extended command. Call the message line
X* routine to read in the command name and apply autocompletion
X* to it. When it comes back, look the name up in the symbol table
X* and run the command if it is found and has the right type.
X* Print an error if there is anything wrong.
X*/
Xchar    extend (f, n, k)
X{
X
X    register    SYMBOL * sp;
X    register char   s;
X    char    xname[NXNAME];
X
X    if ((s = eread (MSG_cmd_t_ex, xname, NXNAME, EFNEW | EFAUTO, NULL)) != TRUE)
X        return (s);
X    if ((sp = symlookup (xname)) != NULL)
X        return ((*sp -> s_funcp) (f, n, KRANDOM));
X    writ_echo (MSG_unk_ext);
X    return (ABORT);
X}
X
X
X/*
X* Read a key from the keyboard, and look it
X* up in the binding table. Display the name of the function
X* currently bound to the key. Say that the key is not bound
X* if it is indeed not bound, or if the type is not a
X* "builtin". This is a bit of overkill, because this is the
X* only kind of function there is.
X*/
Xbool help ()
X{
X    register    SYMBOL * sp;
X    register int    c;
X    char    b[20];
X    char    buf[80];
X
X    writ_echo (MSG_d_b);
X
X    c = getkey ();
X    keyname (b, c);
X    if ((sp = binding[c]) == NULL)
X        {
X        sprintf (buf, MSG_unbd, b);
X        writ_echo (buf);
X        }
X    else
X        {
X        sprintf (buf, MSG_bnd_to, b, sp -> s_name);
X        writ_echo (buf);
X        }
X    return (TRUE);
X}
X
X/*
X*   Sort the lines in the buffer.
X*/
Xvoid    sort_buf (b_ptr, cnt)
XBUFFER  *b_ptr;
Xint     cnt;
X    {
X    LINE    *lp1, *lp2;
X    bool    no_swap;
X    int     loop1, loop2;
X
X    for (loop1 = cnt; loop1 > 0; loop1--)
X        {
X        no_swap = TRUE;
X        lp1 = b_ptr -> b_linep -> l_fp; /* point to first line */
X        lp2 = lp1 -> l_fp;      /* point to next line */
X        for (loop2 = 0; loop2 <= loop1; loop2++)
X            {
X            /* compare strings and swap if necessary */
X            if (0 < strcmp (&lp1 -> l_text[HFUNCCOL], &lp2 -> l_text[HFUNCCOL]))
X                {
X                lp1 -> l_bp -> l_fp = lp2;  /* get pointer to first string */
X                lp2 -> l_fp -> l_bp = lp1;  /* make it point to second string */
X
X                lp1 -> l_fp = lp2 -> l_fp;  
X                lp2 -> l_bp = lp1 -> l_bp;  
X
X                lp1 -> l_bp = lp2;  
X                lp2 -> l_fp = lp1;
X
X                lp2 -> l_file_offset = lp1 -> l_file_offset;
X                lp1 -> l_file_offset = lp2 -> l_file_offset + lp2 -> l_used;
X
X                no_swap = FALSE;
X                }
X            else
X                {
X                /* if no swap then advance both pointers */
X                lp1 = lp2;
X                }
X            lp2 = lp1 -> l_fp;
X            }
X        /* quick exit if sort is finished sooner than expected */
X        if (no_swap)
X            {   
X            return; 
X            }
X        }
X    }
X
X/*
X* This function creates a table, listing all
X* of the command keys and their current bindings, and stores
X* the table in the standard pop-op buffer (the one used by the
X* directory list command, the buffer list command, etc.). This
X* lets the editor produce it's own wall chart. The bindings to
X* "ins-self" are only displayed if there is an argument.
X*/
Xchar    wallchart (f, n, k)
X{
X
X    register char   s;
X    register int    key, i, j;
X    register    SYMBOL * sp;
X    register char  *cp1;
X    register char  *cp2;
X    char    buf[64];
X    WINDOW  *wp;
X
X    if ((s = bclear (blistp)) != TRUE)/* Clear it out.    */
X        return (s);
X    i = 0;
X    (void) strcpy (blistp -> b_fname, MSG_null);
X    blistp -> b_flag = BFVIEW;
X    writ_echo (MSG_bld_wall);
X	sprintf (buf, MSG_wall_head);
X    if (addline (buf) == FALSE)
X		return;
X    for (key = 0; key < NKEYS; ++key)
X        {
X    /* For all keys.    */
X        sp = binding[key];
X        if (sp != NULL &&
X                (f != FALSE || strcmp (sp -> s_name, MSG_ins_self) != 0))
X            {
X            cp1 = &buf[0];
X            while (cp1 < &buf[HFUNCCOL])/* Goto column 3.  */
X                *cp1++ = ' ';
X			if ((sp -> s_modify & SBOUND) == 0)	/* comment out default binding */
X				buf[0] = '#';
X            cp2 = sp -> s_name; /* Add function name.   */
X            while (*cp1++ = *cp2++)
X                ;
X            cp1--;
X            while (cp1 < &buf[HKEY])/* Goto column 32.  */
X                *cp1++ = ' ';
X            keyname (&buf[HKEY], key);
X			cp1 = &buf[strlen(buf)];
X            while (cp1 < &buf[HKEYCODE])/* Goto column 50.  */
X                *cp1++ = ' ';
X			sprintf (&buf[HKEYCODE], "%4X", key);
X            if (addline (buf) == FALSE)
X                break; /* lets go with what we have */
X            i++;
X            }
X        }
X
X	/* list unbound functions lest they get lost */
X	for (j = 0; j < NSHASH; j++)
X		{
X        sp = symbol[j];
X    	while (sp != NULL)
X        	{
X			if (sp -> s_nkey == 0)
X				{
X        	    cp1 = &buf[0];
X            	while (cp1 < &buf[HFUNCCOL])/* Goto column 3.  */
X                	*cp1++ = ' ';
X				buf[0] = '#';
X    	        cp2 = sp -> s_name; /* Add function name.   */
X        	    while (*cp1++ = *cp2++)
X            	    ;
X	            cp1--;
X    	        while (cp1 < &buf[HENDCOL])
X        	        *cp1++ = ' ';
X       	        *cp1 = 0;
X				i++;
X            	if (addline (buf) == FALSE)
X                	break; /* lets go with what we have */
X				}
X    	    sp = sp -> s_symp;
X        	}
X		}
X    sort_buf (blistp, i);      /* sort buffer lines */
X    popblist ();
X    writ_echo (MSG_null);
X    /* make new window the current window */
X    wp = wheadp;
X    while (wp != NULL)
X        {
X        if (wp -> w_bufp == blistp)
X            {
X            curwp = wp;
X            curbp = wp -> w_bufp;
X            return (TRUE);
X            }
X        wp = wp -> w_wndp;
X        }
X    return (TRUE);
X}
X            
X/* check for BEAVFIL and read it in if found
X* - also, set local file variable for bindtokey for saving new defs
X* (this is some what of a hack as it only handles 'bindtokey' changes at 
X* this time - also local file io !!!)
X*/
Xvoid check_extend (sfname)
X
Xchar *sfname;	/* name of startup file (null if default) */
X
X{
X	char *fname;	/* resulting file name to execute */
X	char	rc_name[40];	/* fixed up name of rc file */
X	char	*term;
X	char *getenv();
X    register    SYMBOL * sp;
X    char    funcname[NXNAME + 1];
X    char    keybind[NXNAME + 1];
X    int     keyval;
X    FILE * bindf;
X
X	/* look up the startup file */
X	if ((sfname != NULL) && (*sfname != 0))
X		fname = flook(sfname, TRUE);
X	else
X		{
X#ifdef UNIX
X		/* hidden file under unix */
X		strcpy (&rc_name[0], ".");
X		strcpy (&rc_name[1], MSG_beavrc);
X
X		if ((term = getenv("TERM")) != 0)
X			{
X			strcpy (&rc_name[strlen(rc_name)], ".");
X			strcpy (&rc_name[strlen(rc_name)], term);
X			}
X		fname = flook(rc_name, TRUE);
X		/* if fixed up name is not there then check original */
X		if (fname == NULL)
X		{
X			/* hidden file under unix */
X			strcpy (&rc_name[0], ".");
X			strcpy (&rc_name[1], MSG_beavrc);
X			fname = flook(rc_name, TRUE);
X		}
X#else
X			strcpy (rc_name, MSG_beavrc);
X			fname = flook(rc_name, TRUE);
X#endif
X	}
X	/* if it isn't around, don't sweat it */
X	if (fname == NULL)
X		return;
X
X	if (bindf = fopen(fname, "r"))
X	{
X	char	buffr[80];
X	char	*buffp;
X
X		buffp = buffr;
X		while (fread (buffp++, sizeof(char), 1, bindf) == 1)
X		{
X			/* scanf is unhappy with commas */ 
X			if (buffp[-1] == ',')
X				buffp[-1] = '-';
X
X			/* did we get a whole line */
X			if (buffp[-1] == '\n')
X			{
X				*buffp = 0;	/* terminate line */
X				buffp = buffr;
X				sscanf (buffr, "%s %s %x", funcname, keybind, &keyval);
X				if ((buffr[0] == '#') || (keyval == 0))
X					continue;
X		        if (sp = symlookup (funcname))
X   		        {
X       			    if (binding[keyval] != NULL)/* Unbind old, and  */
X           	    	--binding[keyval] -> s_nkey;
X		            binding[keyval] = sp;/* rebind new.      */
X   			        ++sp -> s_nkey;
X				    sp -> s_modify |= SBOUND;	/* flag as altered key binding */
X           		}
X       		}
X		}
X    	fclose (bindf);
X	}
X}
X
X/*	Look up the existance of a file along the normal or PATH
X	environment variable. Look first in the HOME directory if
X	asked and possible
X*/
X
Xchar *flook(fname, hflag)
X
Xchar *fname;	/* base file name to search for */
Xint hflag;	/* Look in the HOME environment variable first? */
X
X{
X	register char *home;	/* path to home directory */
X	register char *path;	/* environmental PATH variable */
X	register char *sp;	/* pointer into path spec */
X	register int i;		/* index */
X	static char fspec[128];	/* full path spec to search */
X	char *getenv();
X    FILE * bindf;
X
X	if (hflag) {
X		home = getenv("HOME");
X		if (home != NULL) {
X			/* build home dir file spec */
X			strcpy(fspec, home);
X			if (fspec[strlen(fspec) - 1] != '/')
X				strcat(fspec, "/");
X			strcat(fspec, fname);
X
X			/* and try it out */
X			if (bindf = fopen(fspec, "r"))
X			{
X				fclose(bindf);
X				return(fspec);
X			}
X		}
X	}
X
X	/* always try the current directory first */
X	if (bindf = fopen(fname, "r"))
X	{
X		fclose(bindf);
X		return(fname);
X	}
X
X	/* get the PATH variable */
X	path = getenv("PATH");
X	if (path != NULL)
X		while (*path) {
X
X			/* build next possible file spec */
X			sp = fspec;
X			while (*path && (*path != PATHCHR))
X				*sp++ = *path++;
X
X			/* add a terminating dir separator if we need it */
X			if (sp[-1] != SEPCHAR)
X				*sp++ = SEPCHAR;
X
X			*sp = 0;
X			strcat(fspec, fname);
X
X			/* and try it out */
X			if (bindf = fopen(fspec, "r"))
X			{
X				fclose(bindf);
X				return(fspec);
X			}
X
X			if (*path == PATHCHR)
X				++path;
X		}
X
X	return(NULL);	/* no such luck */
X}
X
X
X/* interactive method for loading binding file
X* (uses above routine, obviously)
X*/
Xchar    load_extend ()
X{
X
X#ifdef CUSTOMIZE
X    register char   s;
X    char    fname[NFILEN];
X
X    if ((s = ereply (MSG_bnd_file, fname, NFILEN, NULL)) != TRUE)
X        return (s);
X    check_extend (fname);
X    writ_echo (okmsg);
X#endif
X	return (TRUE);
X}
X
Xint     find_keyval (name)
Xchar   *name;
X{
X    SYMBOL * sp;
X    int     key;
X
X    for (key = 0; key < NKEYS; ++key)
X        {
X    /* For all keys.    */
X        sp = binding[key];
X        if (sp != NULL && (strcmp (sp -> s_name, name) == 0))
X            return (key);
X        }
X    return (0);
X}
END_OF_FILE
if test 12209 -ne `wc -c <'extend.c'`; then
    echo shar: \"'extend.c'\" unpacked with wrong size!
fi
chmod +x 'extend.c'
# end of 'extend.c'
fi
if test -f 'main.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'main.c'\"
else
echo shar: Extracting \"'main.c'\" \(12884 characters\)
sed "s/^X//" >'main.c' <<'END_OF_FILE'
X/*
X*	BEAV is based on the source for emacs for display and keyboard handling 
X* functions.   The binary file handling and display formats are special
X* to BEAV.   There is a full manual included in this release.   There
X* are makefiles for unix and MSC 5.1 under DOS.   The old Wang PC is
X* supported.   This release is for unix.   The def_unix.h file is the
X* header for unix and the def_dos.h file is the header for dos.   Rename 
X* the appropriate .h file to def.h to convert to your os.
X* 	I am willing to maintain BEAV and will entertain suggestions for
X* modifications and/or bug fixes.   I can be reached at;
X*
X* 		pvr@wang.com
X* 
X* or at;
X* 
X* 		Peter Reilley
X* 		19 Heritage Cir.
X* 		Hudson, N.H. 03051
X*/
X
X/*
X*	Bug fix log
X*	3/04/91		1.20		pvr
X*		Create new file with read/write permisions.
X*		Fix polled mode system hog tty bug.
X*		Add ANSI define for DOS.
X*		Define short for D16 type.
X*		Call ttclose on error exit.
X*		Limit nrow and ncol to actual array size.
X*		Added beavrc key binding functionallity.
X*		Added delete current window command.
X*		Support VT100 type function keys for binding.
X*/ 
X/*     
X*
X*     Mainline, macro commands.
X*/
X#include        "def.h"
X
Xchar    execute ();
Xvoid    edinit ();
Xvoid    flush_all ();
Xchar    quit ();
Xchar    ctrlg ();
Xvoid    _lowercase ();
X
X
Xextern    char    MSG_ok[];
Xextern    char    MSG_main[];
Xextern    char    MSG_prog_name[];
Xextern    char    MSG_no_mod[];
Xextern    char    MSG_no_s_chg[];
Xextern    char    MSG_auto_fl[];
Xextern    char    MSG_quit[];
Xextern    char    MSG_not_now[];
Xextern    char    MSG_st_mac[];
Xextern    char    MSG_end_mac[];
Xextern    char    MSG_num_mod[];
Xextern    char    MSG_null[];
X
X#include    "lintfunc.dec"
X
Xint     thisflag;               /* Flags, this command      */
Xint     lastflag;               /* Flags, last command          */
Xint     curgoal;                /* Goal column                  */
Xint     com_line_flags;         /* Count of cmd line switches   */
XBUFFER * curbp;                 /* Current buffer               */
XWINDOW * curwp;                 /* Current window               */
XBUFFER * bheadp;                /* BUFFER listhead              */
XWINDOW * wheadp;                /* WINDOW listhead              */
XBUFFER * blistp;                /* Buffer list BUFFER           */
Xshort   kbdm[NKBDM] = {(KCTLX | ')')};  /* Macro (fitz)  */
Xshort  *kbdmip;                 /* Input  for above             */
Xshort  *kbdmop;                 /* Output for above             */
Xchar    pat[NPAT];              /* Pattern                      */
XSYMBOL * symbol[NSHASH];        /* Symbol table listhead.       */
XSYMBOL * binding[NKEYS];        /* Key bindings.                */
Xextern  ROW_FMT hex_8_fmt;
Xextern  bool    ibm_pc, mem_map;
X
Xchar   *okmsg = {MSG_ok};
Xint     insert_mode = {TRUE};
Xint     extend_buf = {FALSE};
X
Xextern  bool    srch_mode;
Xextern  bool    rplc_mode;
Xextern  char    *getenv ();
Xint     initial_load = 0;
Xint     flush_count = 0;
Xint     flush_num = 500;
Xint     auto_update = 0;
X
Xvoid main (argc, argv)
Xchar   *argv[];
X{
X
X    register    int     c;
X    register    int     f;
X    register    int     n;
X    register    int     mflag;
X    char        bname[NBUFN];
X    register    char    *p;
X    extern      long    last_time;
X    long        last_second;
X
X#if MSDOS
X    is_wang ();                 /* Check for computer type */   
X#endif
X	init_fmt ();				/* initialize format arrays */
X    strcpy (bname, MSG_main);     /* Get buffer name.     */
X    vtinit ();                  /* Virtual terminal.    */
X    keymapinit ();              /* Symbols, bindings.   */
X	
X    if (argc == 1)
X        {
X        edinit (bname);
X        update ();
X        eerase ();
X        }
X
X    else
X        {
X        com_line_flags = 0;
X        initial_load = 1;
X        n = (argc - 1);         /* Load  them backwards */
X        if (n > com_line_flags)
X            {
X/*            _lowercase (argv[n]); */
X            makename (bname, argv[n]);
X            edinit (bname);     /* Buffers, windows.    */
X            update ();
X            readin (argv[n--], 0L, MAXPOS);
X            for (; n > com_line_flags; n--)
X                {
X/*                _lowercase (argv[n]); */
X                load_file (argv[n], 0L, MAXPOS);
X                }
X            }
X        else
X            {
X            edinit (bname);
X            update ();
X            }
X
X        initial_load = 0;
X        }
X
X    check_extend (NULL);  /* check for extended keys */
X    lastflag = 0;               /* Fake last flags.     */
X
Xloop: 
X    update ();
X    c = getkey ();
X    if (epresf != FALSE)
X        {
X        eerase ();
X        update ();
X        }
X    f = FALSE;
X    n = 1;
X    if (c == (KCTRL | 'U'))
X        {
X    /* ^U, start argument.  */
X        f = TRUE;
X        n = 4;
X        while ((c = getkey ()) == (KCTRL | 'U'))
X            n *= 4;
X        if ((c >= '0' && c <= '9') || c == '-')
X            {
X            if (c == '-')
X                {
X                n = 0;
X                mflag = TRUE;
X                }
X            else
X                {
X                n = c - '0';
X                mflag = FALSE;
X                }
X            while ((c = getkey ()) >= '0' && c <= '9')
X                n = 10 * n + c - '0';
X            if (mflag != FALSE)
X                n = -n;
X            }
X        }
X    if (kbdmip != NULL)
X        {
X    /* Save macro strokes.  */
X        if (c != (KCTLX | ')') && kbdmip > &kbdm[NKBDM - 6])
X            {
X            ctrlg (FALSE, 0, KRANDOM);
X            goto loop;
X            }
X        if (f != FALSE)
X            {
X            *kbdmip++ = (KCTRL | 'U');
X            *kbdmip++ = n;
X            }
X        *kbdmip++ = c;
X        }
X    execute (c, f, n);          /* Do it.               */
X    goto loop;
X}
X
X
X/*
X* Command execution. Look up the binding in the the
X* binding array, and do what it says. Return a very bad status
X* if there is no binding, or if the symbol has a type that
X* is not usable (there is no way to get this into a symbol table
X* entry now). Also fiddle with the flags.
X*/
Xchar    execute (c, f, n)
X{
X
X    register    SYMBOL * sp;
X    register int    status;
X
X    if ((sp = binding[c]) != NULL)
X        {
X        thisflag = 0;
X        if (sp -> s_modify & SMOD && (curbp -> b_flag & BFVIEW))
X            {
X            writ_echo (MSG_no_mod);
X            return (ABORT);
X            }
X        if (sp -> s_modify & SSIZE && (curbp -> b_flag & BFSLOCK))
X            {
X            writ_echo (MSG_no_s_chg);
X            return (ABORT);
X            }
X        if ((srch_mode  && !(sp -> s_modify & SSRCH)) ||
X            (rplc_mode  && !(sp -> s_modify & SRPLC)))
X            {
X            ttbeep ();
X            return (TRUE);
X            }
X
X        status = (*sp -> s_funcp) (f, n, c);
X        if (sp -> s_modify & SMOD)
X            flush_count++;
X
X        if (flush_count >= flush_num && auto_update)
X            if (!(kbdmip != NULL || kbdmop != NULL))/* not during macro */
X                {
X                ttbeep ();
X                writ_echo (MSG_auto_fl);
X                flush_all ();
X                }
X        lastflag = thisflag;
X        return (status);
X        }
X    else
X        bad_key (c);
X
X    lastflag = 0;
X    return (ABORT);
X}
X
X
X/*
X* Initialize all of the buffers
X* and windows. The buffer name is passed down as
X* an argument, because the main routine may have been
X* told to read in a file by default, and we want the
X* buffer name to be right.
X*/
Xvoid edinit (bname)
Xchar    bname[];
X{
X
X    register    BUFFER * bp;
X    register    WINDOW * wp;
X
X    bp = bfind (bname, TRUE);   /* Text buffer.         */
X    blistp = bcreate (MSG_null);      /* Special list buffer. */
X    wp = (WINDOW *) malloc (sizeof (WINDOW));/* Initial window.      */
X    if (bp == NULL || wp == NULL || blistp == NULL)
X        abort ();
X    curbp = bp;                 /* Current ones.        */
X    wheadp = wp;
X    curwp = wp;
X    wp -> w_wndp = NULL;        /* Initialize window.   */
X    wp -> w_bufp = bp;
X    bp -> b_nwnd = 1;           /* Displayed.           */
X    wp -> w_fmt_ptr = &hex_8_fmt;/* HEX 8 bit display       pvr  */
X    wp -> w_linep = bp -> b_linep;
X    wp -> w_dotp = bp -> b_linep;
X    wp -> w_doto = 0;           /* set dot pos  pvr */
X    wp -> w_markp = NULL;
X    wp -> w_marko = 0;
X    wp -> w_toprow = 0;
X    wp -> w_ntrows = nrow - 2;  /* 2 = mode, echo.      */
X    wp -> w_flag = WFMODE | WFHARD;/* Full.                */
X    wp -> w_intel_mode = FALSE; /* default is no byte swap     pvr  */
X    wp -> w_disp_shift = 0;     /* default to no byte shift    pvr  */
X    wp -> w_loff = 0;           /* starting line offset        pvr  */
X    wp -> w_unit_offset = 0;    /* dot offset from file start  pvr  */
X}
X
X/*
X* Flush all the dirty buffers that have file names
X* associated with them.
X*/
Xvoid flush_all ()
X{
X    register    BUFFER * bp,
X               *savbp = curbp;
X
X    for (bp = bheadp; bp != NULL; bp = bp -> b_bufp)
X        if (bp -> b_fname != NULL)
X            {
X            curbp = bp;         /* jam */
X            filesave ();
X            update ();
X            }
X    flush_count = 0;
X    writ_echo (okmsg);
X    curbp = savbp;
X    if (blistp -> b_nwnd != 0)  /* update buffer display */
X        listbuffers ();
X    update ();
X}
X
X
X/* call flush_all to empty the buffers
X* and quit
X*/
Xvoid flushnquit (f, n, k)
X{
X    flush_all ();
X    quit (f, n, k);
X}
X
X
X/*
X* Quit command. If an argument, always
X* quit. Otherwise confirm if a buffer has been
X* changed and not written out. Normally bound
X* to "C-X C-C".
X*/
Xchar    quit (f, n, k)
X{
X
X    register char   s;
X
X    if (f != FALSE              /* Argument forces it.  */
X            || anycb () == FALSE/* All buffers clean.   */
X            || (s = eyesno (MSG_quit)) == TRUE)/* User says it's OK.   */
X        {
X
X        vttidy ();
X        exit (GOOD);
X        }
X
X    return (s);
X}
X
X
X/*
X* Begin a keyboard macro.
X* Error if not at the top level
X* in keyboard processing. Set up
X* variables and return.
X*/
Xbool ctlxlp (f, n, k)
X{
X
X    if (kbdmip != NULL || kbdmop != NULL)
X        {
X
X        writ_echo (MSG_not_now);
X        return (FALSE);
X        }
X
X    writ_echo (MSG_st_mac);
X    kbdmip = &kbdm[0];
X    return (TRUE);
X}
X
X
X/*
X* End keyboard macro. Check for
X* the same limit conditions as the
X* above routine. Set up the variables
X* and return to the caller.
X*/
Xbool ctlxrp (f, n, k)
X{
X
X    if (kbdmip == NULL)
X        {
X
X        writ_echo (MSG_not_now);
X        return (FALSE);
X        }
X
X    writ_echo (MSG_end_mac);
X    kbdmip = NULL;
X    return (TRUE);
X}
X
X
X/*
X* Execute a macro.
X* The command argument is the
X* number of times to loop. Quit as
X* soon as a command gets an error.
X* Return TRUE if all ok, else
X* FALSE.
X*/
Xbool ctlxe (f, n, k)
X{
X
X    register int    c;
X    register int    af;
X    register int    an;
X    register int    s;
X
X    if (kbdmip != NULL || kbdmop != NULL)
X        {
X
X        writ_echo (MSG_not_now);
X        return (FALSE);
X        }
X
X    if (n <= 0)
X        return (TRUE);
X    do
X        {
X
X        kbdmop = &kbdm[0];
X        do
X            {
X
X            af = FALSE;
X            an = 1;
X            if ((c = *kbdmop++) == (KCTRL | 'U'))
X                {
X
X                af = TRUE;
X                an = *kbdmop++;
X                c = *kbdmop++;
X                }
X
X            s = TRUE;
X            }
X        while (c != (KCTLX | ')') && (s = execute (c, af, an)) == TRUE);
X        kbdmop = NULL;
X        }
X    while (s == TRUE && --n);
X    return (s);
X}
X
X
X/*
X* Abort.
X* Beep the beeper.
X* Kill off any keyboard macro,
X* etc., that is in progress.
X* Sometimes called as a routine,
X* to do general aborting of
X* stuff.
X*/
Xchar    ctrlg (f, n, k)
X{
X/*    ttbeep (); */
X    if (kbdmip != NULL)
X        {
X        kbdm[0] = (KCTLX | ')');
X        kbdmip = NULL;
X        }
X    return (ABORT);
X}
X
X
X/*
X* Display the version. All this does
X* is copy the text in the external "version" array into
X* the message system, and call the message reading code.
X* Don't call display if there is an argument.
X*/
Xchar    showversion (f, n, k)
X{
Xstatic  char    *cp;
Xchar    buf[80];
X
X    cp = version;
X    sprintf (buf, cp);
X    writ_echo (buf);
X    return (TRUE);
X}
X
X
X/* ughly to_lower function for
X* files read in under MSDOS setargv function
X*/
Xvoid _lowercase (s)
Xregister char  *s;
X{
X
X#ifdef MSDOS
X    for (; *s; s++)
X        if (ISUPPER (*s))
X            *s = TOLOWER (*s);
X#endif
X}
X
X
X/* autosave control
X*/
Xbool autosave ()
X{
X    register    WINDOW * wp;
X    register int    s,
X                    n;
X    char    buf[32];
X
X    if ((s = ereply (MSG_num_mod, buf, sizeof (buf), NULL)) == TRUE)
X        {
X
X        n = atoi (buf);
X        if (n >= 0)
X            auto_update = flush_num = n;/* not 0! */
X        else
X            auto_update = 0;
X        }
X
X    for (wp = wheadp; wp; wp = wp -> w_wndp)
X        if (wp -> w_bufp == curbp)
X            wp -> w_flag |= WFMODE;
X    return (TRUE);
X}
END_OF_FILE
if test 12884 -ne `wc -c <'main.c'`; then
    echo shar: \"'main.c'\" unpacked with wrong size!
fi
chmod +x 'main.c'
# end of 'main.c'
fi
echo shar: End of archive 3 \(of 10\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
>>>>>>>>>>>>>>>> Peter Reilley ..... pvr@wang.com <<<<<<<<<<<<<<<<<<<<<<<
                     Well, that about says it.

pvr@wang.com (Peter Reilley) (06/06/91)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 10)."
# Contents:  line.c symbol.c text.c
# Wrapped by pvr@elf on Thu Mar 14 08:16:46 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'line.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'line.c'\"
else
echo shar: Extracting \"'line.c'\" \(18200 characters\)
sed "s/^X//" >'line.c' <<'END_OF_FILE'
X/*
X*       Text line handling.
X* The functions in this file
X* are a general set of line management
X* utilities. They are the only routines that
X* touch the text. They also touch the buffer
X* and window structures, to make sure that the
X* necessary updating gets done. There are routines
X* in this file that handle the kill buffer too.
X* It isn't here for any good reason.
X*
X* Note that this code only updates the dot and
X* mark values in the window list. Since all the code
X* acts on the current window, the buffer that we
X* are editing must be being displayed, which means
X* that "b_nwnd" is non zero, which means that the
X* dot and mark values in the buffer headers are
X* nonsense.
X*/
X
X#include    "def.h"
X
Xbool ldelnewline_p ();
Xvoid l_fix_up ();
Xbool kinsert ();
X
X
Xextern    char    MSG_cnt_alloc[];
Xextern    char    MSG_too_m_k[];
X#if RUNCHK
Xextern    char    ERR_no_alloc[];
Xextern    char    ERR_db_dalloc[];
Xextern    char    ERR_lock[];
Xextern    char    ERR_lock_del[];
X#endif
X#include    "lintfunc.dec"
X
X#ifndef KBLOCK
X#define KBLOCK  256             /* Kill buffer block size.  */
X#endif
X
Xchar   *kbufp = NULL;           /* Kill buffer data.        */
Xint     kused = 0;              /* # of bytes used in KB.   */
Xint     ksize = 0;              /* # of bytes allocated in KB.  */
X
Xextern  LINE    *cur_pat;
Xextern  LINE    *cur_mask;
Xextern  bool    read_pat_mode;
X
X/*
X* This routine allocates a block
X* of memory large enough to hold a LINE
X* containing "used" characters. The block is
X* always rounded up a bit. Return a pointer
X* to the new block, or NULL if there isn't
X* any memory left. Print a message in the
X* message line if no space.
X*/
XLINE * lalloc (used)
Xregister int    used;
X{
X    register    LINE * lp;
X    char    buf[80], buf1[50];
X#if RUNCHK
X    if (read_pat_mode)
X        printf (ERR_no_alloc);
X#endif
X
X    if ((lp = (LINE *) malloc (sizeof (LINE) + used)) == NULL)
X        {
X        sprintf (buf1, MSG_cnt_alloc, R_POS_FMT(curwp));
X        sprintf (buf, buf1, (A32)used);
X        writ_echo (buf);
X        curbp -> b_flag |= BFBAD;/* may be trashed */
X        curwp -> w_flag |= WFMODE;
X        update ();
X        return (NULL);
X        }
X    lp -> l_size = used;
X    lp -> l_used = used;
X    lp -> l_file_offset = 0;    /* set resonable initial value */
X    return (lp);
X}
X
X
X/*
X* Delete line "lp". Fix all of the
X* links that might point at it (they are
X* moved to offset 0 of the next line.
X* Unlink the line from whatever buffer it
X* might be in. Release the memory. The
X* buffers are updated too; the magic conditions
X* described in the above comments don't hold
X* here.
X*/
X
Xvoid lfree (lp)
Xregister    LINE * lp;
X{
X    register    BUFFER * bp;
X    register    WINDOW * wp;
X
X#if RUNCHK
X    if (read_pat_mode)
X        printf (ERR_db_dalloc);
X#endif
X
X    wp = wheadp;
X    while (wp != NULL)
X        {
X        if (wp -> w_linep == lp)
X            {
X            wp -> w_linep = lp -> l_fp;
X            wp -> w_loff = 0;
X            }
X
X        if (wp -> w_dotp == lp)
X            {
X            wp -> w_dotp = lp -> l_fp;
X            wp -> w_doto = 0;
X            }
X
X        if (wp -> w_markp == lp)
X            {
X            wp -> w_markp = lp -> l_fp;
X            wp -> w_marko = 0;
X            }
X
X        wp = wp -> w_wndp;
X        }
X
X    bp = bheadp;
X    while (bp != NULL)
X        {
X
X        if (bp -> b_nwnd == 0)
X            {
X            if (bp -> b_dotp == lp)
X                {
X                bp -> b_dotp = lp -> l_fp;
X                bp -> b_doto = 0;
X                }
X
X            if (bp -> b_markp == lp)
X                {
X                bp -> b_markp = lp -> l_fp;
X                bp -> b_marko = 0;
X                }
X            }
X        bp = bp -> b_bufp;
X        }
X
X    lp -> l_bp -> l_fp = lp -> l_fp;
X    lp -> l_fp -> l_bp = lp -> l_bp;
X    free ((char *) lp);
X}
X
X
X/*
X* This routine gets called when
X* a character is changed in place in the
X* current buffer. It updates all of the required
X* flags in the buffer and window system. The flag
X* used is passed as an argument; if the buffer is being
X* displayed in more than 1 window we change EDIT to
X* HARD. Set MODE if the mode line needs to be
X* updated (the "*" has to be set).
X*/
Xvoid lchange (flag)
Xregister int    flag;
X{
X    register    WINDOW * wp;
X
X    if (curbp -> b_nwnd != 1)   /* Ensure hard.     */
X        flag = WFHARD;
X    if ((curbp -> b_flag & BFCHG) == 0)
X        {
X    /* First change, so     */
X        flag |= WFMODE;         /* update mode lines.   */
X        curbp -> b_flag |= BFCHG;
X        }
X
X    wp = wheadp;
X    while (wp != NULL)
X        {
X        if (wp -> w_bufp == curbp)
X            wp -> w_flag |= flag;
X        wp = wp -> w_wndp;
X        }
X}
X
X
X/*
X* Insert "n" copies of the character "c"
X* at the current location of dot. In the easy case
X* all that happens is the text is stored in the line.
X* Always allocate some extra space in line so that edit 
X* will be faster next time but will save space in the general case.
X* In the hard case, the line has to be reallocated.
X* When the window list is updated, take special
X* care; I screwed it up once. You always update dot
X* in the current window. You update mark, and a
X* dot in another window, if it is greater than
X* the place where you did the insert. Return TRUE
X* if all is well, and FALSE on errors.
X*/
Xbool linsert (n, c)
X{
X    register char  *cp1;
X    register char  *cp2;
X    register    LINE * lp1;
X    register    LINE * lp2;
X    register    LINE * lp3;
X    register short  doto;
X    register int    i;
X    register    WINDOW * wp;
X
X#if RUNCHK
X    /* check that buffer size can be changed */
X    if (curbp -> b_flag & BFSLOCK)
X    {
X        writ_echo (ERR_lock);
X        return (FALSE);
X    }
X#endif
X
X    lchange (WFMOVE);
X    lp1 = curwp -> w_dotp;      /* Current line     */
X    if (lp1 == curbp -> b_linep)
X        {
X       /* At the end: special  */
X        if ((lp2 = lalloc (n + NBLOCK)) == NULL)/* Allocate new line    */
X            return (FALSE);
X        lp2 -> l_used = n;      /* set to correct size */
X        lp3 = lp1 -> l_bp;      /* Previous line    */
X        lp3 -> l_fp = lp2;      /* Link in      */
X        lp2 -> l_fp = lp1;
X        lp1 -> l_bp = lp2;
X        lp2 -> l_bp = lp3;
X        for (i = 0; i < n; ++i)
X            lp2 -> l_text[i] = c;
X        curwp -> w_dotp = lp2;
X        curwp -> w_doto = n;
X        lp2 -> l_file_offset = lp1 -> l_file_offset + lp1 -> l_used;
X        l_fix_up (lp2); /* re-adjust file offsets */
X        return (TRUE);
X        }
X
X    doto = curwp -> w_doto;     /* Save for later.  */
X    if (lp1 -> l_used + n > lp1 -> l_size)
X        {
X    /* Hard: reallocate */
X        if ((lp2 = lalloc (lp1 -> l_used + n + NBLOCK)) == NULL)
X            return (FALSE);
X        lp2 -> l_used = lp1 -> l_used + n;  /* set to correct size */
X        cp1 = &lp1 -> l_text[0];
X        cp2 = &lp2 -> l_text[0];
X        while (cp1 != &lp1 -> l_text[doto])
X            *cp2++ = *cp1++;
X        cp2 += n;
X        while (cp1 != &lp1 -> l_text[lp1 -> l_used])
X            *cp2++ = *cp1++;
X        lp1 -> l_bp -> l_fp = lp2;
X        lp2 -> l_fp = lp1 -> l_fp;
X        lp1 -> l_fp -> l_bp = lp2;
X        lp2 -> l_bp = lp1 -> l_bp;
X        lp2 -> l_file_offset = lp1 -> l_file_offset;
X        free ((char *) lp1);
X        }
X    else
X        {
X    /* Easy: in place   */
X        lp2 = lp1;              /* Pretend new line */
X        lp2 -> l_used += n;
X        cp2 = &lp1 -> l_text[lp1 -> l_used];
X        cp1 = cp2 - n;
X        while (cp1 != &lp1 -> l_text[doto])
X            *--cp2 = *--cp1;
X        }
X
X    for (i = 0; i < n; ++i)     /* Add the characters   */
X        lp2 -> l_text[doto + i] = c;
X    wp = wheadp;                /* Update windows   */
X    while (wp != NULL)
X        {
X        if (wp -> w_linep == lp1)
X            {
X            wp -> w_linep = lp2;
X            }
X
X        if (wp -> w_dotp == lp1)
X            {
X            wp -> w_dotp = lp2;
X            if (wp == curwp || wp -> w_doto > doto)
X                wp -> w_doto += n;
X            }
X
X        if (wp -> w_markp == lp1)
X            {
X            wp -> w_markp = lp2;
X            if (wp -> w_marko > doto)
X                wp -> w_marko += n;
X            }
X
X        wp = wp -> w_wndp;
X        }
X    l_fix_up (curwp -> w_dotp);   /* re-adjust file offsets */
X    return (TRUE);
X}
X
X
X/*
X* This function deletes "n" bytes,
X* starting at dot. It understands how to deal
X* with end of lines, etc. It returns TRUE if all
X* of the characters were deleted, and FALSE if
X* they were not (because dot ran into the end of
X* the buffer). The "kflag" is TRUE if the text
X* should be put in the kill buffer.
X*/
Xbool ldelete (n, kflag)
X{
X    register char  *cp1;
X    register char  *cp2;
X    register    LINE * dotp;
X    register short  doto, l_size, prev_size;
X    register    WINDOW * wp;
X
X#if RUNCHK
X    /* check that buffer size can be changed */
X    if (curbp -> b_flag & BFSLOCK)
X    {
X        writ_echo (ERR_lock_del);
X        return (FALSE);
X    }
X#endif
X    
X    doto = curwp -> w_doto;
X
X    lchange (WFMOVE);
X        
X    prev_size = 0;
X    while (((l_size = curwp -> w_dotp -> l_used) - doto) < n)
X        {
X        /* break out when there are no more lines to delete */
X        if (l_size == prev_size)
X            break;
X        /* Must merge the two lines. */
X        if (ldelnewline_p () == FALSE)
X            return (FALSE);
X        prev_size = l_size;
X        }
X
X    dotp = curwp -> w_dotp;
X
X    /* if at the end of the buffer then delete nothing */
X    if (doto >= dotp -> l_used)
X        {
X        l_fix_up (dotp);    /* re-adjust file offsets */
X        return (TRUE);
X        }
X    cp1 = &dotp -> l_text[doto];/* Scrunch text.    */
X    cp2 = cp1 + n;
X
X    /* put stuff to delete into the kill buffer */
X    if (kflag != FALSE)
X        {
X        /* Kill?        */
X        while (cp1 != cp2)
X            {
X            if (kinsert (*cp1) == FALSE)
X                return (FALSE);
X            ++cp1;
X            }
X
X        cp1 = &dotp -> l_text[doto];
X        }
X        /* kill bytes in the current line */
X    while (cp2 < &dotp -> l_text[dotp -> l_used])
X        *cp1++ = *cp2++;
X
X    dotp -> l_used -= n;
X    wp = wheadp;            /* Fix windows      */
X    while (wp != NULL)
X        {
X        if (wp -> w_dotp == dotp && wp -> w_doto >= doto)
X            {
X            wp -> w_doto -= n;
X            if (wp -> w_doto < doto)
X                wp -> w_doto = doto;
X            }
X
X        if (wp -> w_markp == dotp && wp -> w_marko >= doto)
X            {
X            wp -> w_marko -= n;
X            if (wp -> w_marko < doto)
X                wp -> w_marko = doto;
X            }
X
X        wp = wp -> w_wndp;
X        }
X    l_fix_up (curwp -> w_dotp);    /* re-adjust file offsets */
X    return (TRUE);
X}
X
X
X/*
X* Delete a newline. Join the current line
X* with the next line. Always allocate some extra space, if this
X* line was edited ones then it will probably be again. It will
X* go faster the second time. If the next line is the magic
X* header line always return TRUE; merging the last line
X* with the header line can be thought of as always being a
X* successful operation, even if nothing is done, and this makes
X* the kill buffer work "right". Easy cases can be done by
X* shuffling data around. Hard cases require that lines be moved
X* about in memory. Return FALSE on error and TRUE if all
X* looks ok. Called by "ldelete" only.
X*/
Xbool ldelnewline_p ()
X{
X
X    register char  *cp1;
X    register char  *cp2;
X    register    LINE * lp1;
X    register    LINE * lp2;
X    register    LINE * lp3;
X    register    WINDOW * wp;
X
X    lp1 = curwp -> w_dotp;
X    lp2 = lp1 -> l_fp;
X    if (lp2 == curbp -> b_linep)
X        {
X        /* At the buffer end.   */
X        if (lp1 -> l_used == 0) /* Blank line.      */
X            lfree (lp1);
X        return (TRUE);
X        }
X
X    /* will next line fit in current line? */
X    if (lp2 -> l_used <= lp1 -> l_size - lp1 -> l_used)
X        {
X
X        cp1 = &lp1 -> l_text[lp1 -> l_used];
X        cp2 = &lp2 -> l_text[0];
X        while (cp2 != &lp2 -> l_text[lp2 -> l_used])
X            *cp1++ = *cp2++;
X        wp = wheadp;
X        while (wp != NULL)
X            {
X
X            if (wp -> w_linep == lp2)
X                {
X                wp -> w_linep = lp1;
X                wp -> w_loff += lp1 -> l_used;
X                }
X
X            if (wp -> w_dotp == lp2)
X                {
X                wp -> w_dotp = lp1;
X                wp -> w_doto += lp1 -> l_used;
X                }
X
X            if (wp -> w_markp == lp2)
X                {
X                wp -> w_markp = lp1;
X                wp -> w_marko += lp1 -> l_used;
X                }
X
X            wp = wp -> w_wndp;
X            }
X
X        lp1 -> l_used += lp2 -> l_used;
X        lp1 -> l_fp = lp2 -> l_fp;
X        lp2 -> l_fp -> l_bp = lp1;
X        free ((char *) lp2);
X        return (TRUE);
X        }
X
X    /* lines too big so allocate a new one */
X    if ((lp3 = lalloc (lp1 -> l_used + lp2 -> l_used + NBLOCK)) == NULL)
X        return (FALSE);
X    lp3 -> l_used = lp1 -> l_used + lp2 -> l_used;  /* set to correct size */
X    cp1 = &lp1 -> l_text[0];
X    cp2 = &lp3 -> l_text[0];
X    while (cp1 != &lp1 -> l_text[lp1 -> l_used])
X        *cp2++ = *cp1++;
X    cp1 = &lp2 -> l_text[0];
X    while (cp1 != &lp2 -> l_text[lp2 -> l_used])
X        *cp2++ = *cp1++;
X    lp1 -> l_bp -> l_fp = lp3;
X    lp3 -> l_fp = lp2 -> l_fp;
X    lp2 -> l_fp -> l_bp = lp3;
X    lp3 -> l_bp = lp1 -> l_bp;
X    lp3 -> l_file_offset = lp1 -> l_file_offset;
X    wp = wheadp;
X    while (wp != NULL)
X        {
X
X        if (wp -> w_linep == lp1 || wp -> w_linep == lp2)
X            {
X            wp -> w_linep = lp3;
X            if (wp -> w_linep == lp2)
X                wp -> w_loff += lp1 -> l_used;
X            }
X
X        if (wp -> w_dotp == lp1)
X            wp -> w_dotp = lp3;
X        else
X            if (wp -> w_dotp == lp2)
X                {
X                wp -> w_dotp = lp3;
X                wp -> w_doto += lp1 -> l_used;
X                }
X
X        if (wp -> w_markp == lp1)
X            wp -> w_markp = lp3;
X        else
X            if (wp -> w_markp == lp2)
X                {
X                wp -> w_markp = lp3;
X                wp -> w_marko += lp1 -> l_used;
X                }
X
X        wp = wp -> w_wndp;
X        }
X
X    free ((char *) lp1);
X    free ((char *) lp2);
X    return (TRUE);
X}
X
X/*
X*   Replace character at dot position.
X*/
Xbool    lreplace (n, c)
Xint     n;
Xchar    c;
X    {
X    lchange (WFEDIT);
X    while (n--)
X        {
X        DOT_CHAR(curwp) = c & 0xff;
X        move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
X        }
X    }   
X    
X/*
X* Replace plen characters before dot with argument string.
X*/
Xbool lrepl_str (plen, rstr, mstr)
X
Xregister int    plen;           /* length to remove     */
Xregister LINE   *rstr;          /* replace string       */
Xregister LINE   *mstr;          /* mask string       */
X{
X    register    int    i;       /* used for random characters   */
X    register    LINE   *dotp;   /* pointer to line structure */
X    register    int    doto;    /* offset into line     */
X    register    int     rlen;   /* rplace string length */
X    register    char    c;      /* temp storage for char */
X    register    char    mask;   /* temp storage for mask */
X
X /* 
X  * make the string lengths match (either pad the line
X  * so that it will fit, or scrunch out the excess).
X  * be careful with dot's offset.
X  */
X    doto = curwp -> w_doto;
X    rlen = rstr -> l_used;
X    if (plen > rlen)
X        {
X        ldelete (plen - rlen, FALSE);
X        }
X    else if (plen < rlen)
X        {
X        if (linsert (rlen - plen, ' ') == FALSE)
X            return (FALSE);
X        }
X    curwp -> w_doto = doto;
X    dotp = curwp -> w_dotp;     /* save dot line for later */
X
X    /* do the replacement. */
X    for (i = 0; i < rlen; i++)
X    {
X        c = DOT_CHAR(curwp);
X        mask = mstr -> l_text[i];
X        DOT_CHAR(curwp) = (c & mask) | (rstr -> l_text[i] & ~mask);
X        move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
X    }
X    curwp -> w_doto = doto;
X    curwp -> w_dotp = dotp;
X    lchange (WFHARD);
X    return (TRUE);
X}
X
X
X/*
X* Delete all of the text
X* saved in the kill buffer. Called by commands
X* when a new kill context is being created. The kill
X* buffer array is released, just in case the buffer has
X* grown to immense size. No errors.
X*/
Xvoid kdelete ()
X{
X    if (kbufp != NULL)
X        {
X        free ((char *) kbufp);
X        kbufp = NULL;
X        kused = 0;
X        ksize = 0;
X        }
X}
X
X/*
X* Insert a character to the kill buffer,
X* enlarging the buffer if there isn't any room. Always
X* grow the buffer in chunks, on the assumption that if you
X* put something in the kill buffer you are going to put
X* more stuff there too later. Return TRUE if all is
X* well, and FALSE on errors. Print a message on
X* errors.
X*/
Xbool kinsert (c)
X{
X    register char  *nbufp;
X    register int    i;
X
X    if (kused == ksize)
X        {
X        if ((nbufp = malloc (ksize + KBLOCK)) == NULL)
X            {
X            writ_echo (MSG_too_m_k);
X            return (FALSE);
X            }
X        for (i = 0; i < ksize; ++i)
X            nbufp[i] = kbufp[i];
X        if (kbufp != NULL)
X            free ((char *) kbufp);
X        kbufp = nbufp;
X        ksize += KBLOCK;
X        }
X    kbufp[kused++] = c;
X    return (TRUE);
X}
X
X
X/*
X* This function gets characters from
X* the kill buffer. If the character index "n" is
X* off the end, it returns "-1". This lets the caller
X* just scan along until it gets a "-1" back.
X*/
Xchar    kremove (n)
X{
X    if      (n >= kused)
X                return (-1);
X    return (kbufp[n] & 0xFF);
X}
X
X/*
X*   Line fixup.
X*   This fixes the 'l_file_offset' variable in
X*   each line structure.
X*   This is necessary after every change in the size
X*   of the buffer.
X*/
Xvoid l_fix_up (line)
X
XLINE * line;                    /* points to buffer header line */
X
X{
X    long    offset;
X    LINE * end_line;
X
X    end_line = curwp -> w_bufp -> b_linep;/* header line */
X
X    if (line == NULL)
X        line = end_line -> l_fp;/* point to first line */
X
X    offset = line -> l_file_offset;/* starting offset */
X    offset += line -> l_used;
X    while ((line = line -> l_fp) != end_line)
X        {
X        line -> l_file_offset = offset;
X        offset += line -> l_used;
X        }
X}
X
X
X
END_OF_FILE
if test 18200 -ne `wc -c <'line.c'`; then
    echo shar: \"'line.c'\" unpacked with wrong size!
fi
chmod +x 'line.c'
# end of 'line.c'
fi
if test -f 'symbol.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'symbol.c'\"
else
echo shar: Extracting \"'symbol.c'\" \(18972 characters\)
sed "s/^X//" >'symbol.c' <<'END_OF_FILE'
X/*
X*              Symbol table stuff.
X* Symbol tables, and keymap setup.
X* The terminal specific parts of building the
X* keymap has been moved to a better place.
X*/
X#define LINT_ARGS   1           /* enable lint type checking */
X#include        "def.h"
X
Xvoid keyadd ();
Xvoid keydup ();
X
X
Xextern    char    MSG_byte_shift[];
Xextern    char    MSG_back_char[];
Xextern    char    MSG_quit[];
Xextern    char    MSG_forw_del_char[];
Xextern    char    MSG_toggle_swap[];
Xextern    char    MSG_forw_char[];
Xextern    char    MSG_abort[];
Xextern    char    MSG_ins_self[];
Xextern    char    MSG_back_del_char[];
Xextern    char    MSG_refresh[];
Xextern    char    MSG_forw_line[];
Xextern    char    MSG_back_line[];
Xextern    char    MSG_quote[];
Xextern    char    MSG_recall[];
Xextern    char    MSG_twiddle[];
Xextern    char    MSG_forw_page[];
Xextern    char    MSG_kill_region[];
Xextern    char    MSG_yank[];
Xextern    char    MSG_down_window[];
Xextern    char    MSG_ins_toggle[];
Xextern    char    MSG_display_buffers[];
Xextern    char    MSG_quit[];
Xextern    char    MSG_exit_flush_all[];
Xextern    char    MSG_set_file_name[];
Xextern    char    MSG_file_insert[];
Xextern    char    MSG_buf_size_lock[];
Xextern    char    MSG_flush_all[];
Xextern    char    MSG_down_window[];
Xextern    char    MSG_up_window[];
Xextern    char    MSG_file_read[];
Xextern    char    MSG_file_save[];
Xextern    char    MSG_file_visit[];
Xextern    char    MSG_file_write[];
Xextern    char    MSG_swap_dot_and_mark[];
Xextern    char    MSG_shrink_window[];
Xextern    char    MSG_display_position[];
Xextern    char    MSG_start_macro[];
Xextern    char    MSG_end_macro[];
Xextern    char    MSG_help[];
Xextern    char    MSG_only_window[];
Xextern    char    MSG_del_window[];
Xextern    char    MSG_split_window[];
Xextern    char    MSG_use_buffer[];
Xextern    char    MSG_spawn_cli[];
Xextern    char    MSG_execute_macro[];
Xextern    char    MSG_goto_line[];
Xextern    char    MSG_ins_unit[];
Xextern    char    MSG_kill_buffer[];
Xextern    char    MSG_load_bindings[];
Xextern    char    MSG_forw_window[];
Xextern    char    MSG_back_window[];
Xextern    char    MSG_view_file[];
Xextern    char    MSG_enlarge_window[];
Xextern    char    MSG_ascii_mode[];
Xextern    char    MSG_binary_mode[];
Xextern    char    MSG_buffer_name[];
Xextern    char    MSG_decimal_mode[];
Xextern    char    MSG_ebcdic_mode[];
Xextern    char    MSG_hex_mode[];
Xextern    char    MSG_back_del_unit[];
Xextern    char    MSG_octal_mode[];
Xextern    char    MSG_display_version[];
Xextern    char    MSG_unit_size1[];
Xextern    char    MSG_unit_size2[];
Xextern    char    MSG_unit_size4[];
Xextern    char    MSG_reposition_window[];
Xextern    char    MSG_set_mark[];
Xextern    char    MSG_goto_eob[];
Xextern    char    MSG_goto_bob[];
Xextern    char    MSG_next_buff[];
Xextern    char    MSG_prev_buff[];
Xextern    char    MSG_query_replace[];
Xextern    char    MSG_display_bindings[];
Xextern    char    MSG_auto_save[];
Xextern    char    MSG_back_unit[];
Xextern    char    MSG_compare[];
Xextern    char    MSG_forw_del_unit[];
Xextern    char    MSG_forw_unit[];
Xextern    char    MSG_link_windows[];
Xextern    char    MSG_print[];
Xextern    char    MSG_back_search[];
Xextern    char    MSG_forw_search[];
Xextern    char    MSG_back_page[];
Xextern    char    MSG_copy_region[];
Xextern    char    MSG_extended_command[];
Xextern    char    MSG_up_window[];
Xextern    char    MSG_search_again[];
Xextern    char    MSG_bind_to_key[];
Xextern    char    MSG_file_visit_split[];
Xextern    char    MSG_yank_buffer[];
Xextern    char    MSG_save_region[];
Xextern    char    MSG_use_buffer_split[];
Xextern    char    MSG_no_f_tb[];
X
X/*
X* Defined by "main.c".
X*/
Xextern char ctrlg ();           /* Abort out of things      */
Xextern char quit ();            /* Quit             */
Xextern char ctlxlp ();          /* Begin macro          */
Xextern char ctlxrp ();          /* End macro            */
Xextern char ctlxe ();           /* Execute macro        */
Xextern char showversion ();     /* Show version numbers, etc.   */
Xextern char flushnquit ();      /* Flush buffers & exit (fitz)  */
Xextern char flush_all ();       /* Flush buffers (jam)      */
Xextern char autosave ();        /* autosave function (jam)  */
X
X/*
X* Defined by "search.c".
X*/
Xextern char forwsearch ();      /* Search forward       */
Xextern char backsearch ();      /* Search backwards     */
Xextern char searchagain ();     /* Repeat last search command   */
Xextern char queryrepl ();       /* Query replace        */
Xextern char compare ();         /* Compare two windows  */
Xextern char recall ();          /* Recall last search string  */
X
X/*
X* Defined by "basic.c".
X*/
Xextern char backchar ();        /* Move backward by characters  */
Xextern char forwchar ();        /* Move forward by characters   */
Xextern char gotobob ();         /* Move to start of buffer  */
Xextern char gotoeob ();         /* Move to end of buffer    */
Xextern char forwline ();        /* Move forward by lines    */
Xextern char backline ();        /* Move backward by lines   */
Xextern char forwpage ();        /* Move forward by pages    */
Xextern char backpage ();        /* Move backward by pages   */
Xextern char setmark ();         /* Set mark         */
Xextern char swapmark ();        /* Swap "." and mark        */
Xextern char gotoline ();        /* Go to a specified line.  */
X
X/*
X* Defined by "buffer.c".
X*/
Xextern char listbuffers ();     /* Display list of buffers  */
Xextern char usebuffer ();       /* Switch a window to a buffer  */
Xextern char use_buffer ();      /* ditto, plus window split */
Xextern char killbuffer ();      /* Make a buffer go away.   */
Xextern char next_buf ();        /* goto next buffer     */
Xextern char prev_buf ();        /* goto prev buffer     */
Xextern char yank_buffer ();     /* yank buffer by name      */
Xextern char buffername ();      /* change buffer name       */
Xextern char bufsizlock ();      /* lock buffer size         */
X
X/*
X* Defined by "file."
X*/
Xextern char fileread ();        /* Get a file, read only    */
Xextern char filevisit ();       /* Get a file, read write   */
Xextern char file_visit ();      /* ditto , plus window split    */
Xextern char filewrite ();       /* Write a file         */
Xextern char filesave ();        /* Save current file        */
Xextern char filename ();        /* Adjust file name     */
Xextern char fileinsert ();      /* insert file to cursor (jam ) */
Xextern char viewfile ();        /* readonly file visit (jam)    */
X
X/*
X* Defined by "random.c".
X*/
X
Xextern char dispshift ();       /* Increment display shift   */
Xextern char selfinsert ();      /* Insert character  */
Xextern char insert_toggle ();   /* toggle insert mode  (jam)    */
Xextern char insertunit ();      /* insert unit  (pvr)    */
Xextern char showcpos ();        /* Show the cursor position */
Xextern char twiddle ();         /* Twiddle units        */
Xextern char forwdel ();         /* Forward delete       */
Xextern char backdel ();         /* Backward delete      */
Xextern char quote ();           /* Insert literal       */
Xextern char asciimode ();       /* display ASCII data   */
Xextern char ebcdicmode ();      /* display EBCDIC data   */
Xextern char decimalmode ();     /* display DECIMAL data   */
Xextern char hexmode ();         /* display HEX data   */
Xextern char octalmode ();       /* display OCTAL data   */
Xextern char binarymode ();      /* display BINARY data   */
Xextern char dispsize1 ();       /* display in BYTE format */
Xextern char dispsize2 ();       /* display in WORD format */
Xextern char dispsize4 ();       /* display in DWORD format*/
Xextern char dispswapbyte ();    /* Display swaped bytes    pvr   */
Xextern char yank ();            /* Yank back from killbuffer.   */
Xextern char linkwind ();        /* Link all windows on one buffer. */
X
X/*
X* Defined by "region.c".
X*/
Xextern char killregion ();      /* Kill region.         */
Xextern char copyregion ();      /* Copy region to kill buffer.  */
Xextern char save_region ();     /* Save region in named buffer. */
X
X/*
X* Defined by "spawn.c".
X*/
Xextern char spawncli ();        /* Run CLI in a subjob.     */
Xextern char clock ();           /* display time in modeline */
X
X/*
X* Defined by "window.c".
X*/
Xextern char reposition ();      /* Reposition window        */
Xextern char refresh ();         /* Refresh the screen       */
Xextern char nextwind ();        /* Move to the next window  */
Xextern char prevwind ();        /* Move to the previous window  */
Xextern char mvdnwind ();        /* Move window down     */
Xextern char mvupwind ();        /* Move window up       */
Xextern char onlywind ();        /* Make current window only one */
Xextern char delwind ();         /* Delete current window */
Xextern char splitwind ();       /* Split current window     */
Xextern char enlargewind ();     /* Enlarge display window.  */
Xextern char shrinkwind ();      /* Shrink window.       */
X
X/*
X* Defined by "word.c".
X*/
Xextern char backunit ();        /* Backup by units      */
Xextern char forwunit ();        /* Advance by units     */
Xextern char delfunit ();        /* Delete forward unit. */
Xextern char delbunit ();        /* Delete backward unit.    */
X
X/*
X* Defined by "extend.c".
X*/
Xextern char extend ();          /* Extended commands.       */
Xextern char help ();            /* Help key.            */
Xextern char bindtokey ();       /* Modify key bindings.     */
Xextern char wallchart ();       /* Make wall chart.     */
Xextern char check_extend ();    /* load extended key file   */
Xextern char load_extend ();     /* load extended file by name   */
X
X/*
X* Defined by "display.c
X*/
Xextern char print ();           /* print window from mark to dot */
X
Xtypedef struct
X{
X
X    short   k_key;              /* Key to bind.                 */
X    char    (*k_funcp) ();      /* Function.            */
X    char   *k_name;             /* Function name string.        */
X    char    k_modify;           /* modify bit */
X}
X                KEY;
X
X/*
X* Default key binding table. This contains
X* the function names, the symbol table name, and (possibly)
X* a key binding for the builtin functions. There are no
X* bindings for C-U or C-X. These are done with special
X* code, but should be done normally.
X*/
XKEY key[] =
X{
X        KCTRL | 'A', dispshift, MSG_byte_shift, 0,
X        KCTRL | 'B', backchar, MSG_back_char, SSRCH | SRPLC,
X        KCTRL | 'C', quit, MSG_quit, 0,/* pvr */
X        KCTRL | 'D', forwdel, MSG_forw_del_char, SMOD | SSIZE | SSRCH | SRPLC,
X        KCTRL | 'E', dispswapbyte, MSG_toggle_swap, SSRCH | SRPLC,/* pvr */
X        KCTRL | 'F', forwchar, MSG_forw_char, SSRCH | SRPLC,
X        KCTRL | 'G', ctrlg, MSG_abort, SSRCH | SRPLC,
X        KCTRL | 'I', selfinsert, MSG_ins_self, SMOD | SSRCH | SRPLC,
X        KCTRL | 'H', backdel, MSG_back_del_char, SMOD | SSIZE | SSRCH | SRPLC,
X        KCTRL | 'L', refresh, MSG_refresh, SSRCH | SRPLC,
X        KCTRL | 'N', forwline, MSG_forw_line, SSRCH | SRPLC,
X        KCTRL | 'P', backline, MSG_back_line, SSRCH | SRPLC,
X        KCTRL | 'Q', quote, MSG_quote, 0,
X        KCTRL | 'R', recall, MSG_recall, SSRCH | SRPLC,
X        KCTRL | 'T', twiddle, MSG_twiddle, SMOD | SSRCH | SRPLC,
X        KCTRL | 'V', forwpage, MSG_forw_page, SRPLC,
X        KCTRL | 'W', killregion, MSG_kill_region, SMOD | SSIZE,
X        KCTRL | 'Y', yank, MSG_yank, SMOD | SSIZE,
X        KCTRL | 'Z', mvdnwind, MSG_down_window, 0,/* fitz */
X        KCTLX | KCTRL | 'A', insert_toggle, MSG_ins_toggle, SSRCH | SRPLC,
X        KCTLX | KCTRL | 'B', listbuffers, MSG_display_buffers, 0,
X        KCTLX | KCTRL | 'C', quit, MSG_quit, 0,
X        KCTLX | KCTRL | 'E', flushnquit, MSG_exit_flush_all, 0,/* fitz */
X        KCTLX | KCTRL | 'F', filename, MSG_set_file_name, SMOD,/* jam */
X        KCTLX | KCTRL | 'I', fileinsert, MSG_file_insert, SMOD | SSIZE,
X        KCTLX | KCTRL | 'L', bufsizlock, MSG_buf_size_lock, 0,
X        KCTLX | KCTRL | 'M', flush_all, MSG_flush_all, 0,
X        KCTLX | KCTRL | 'N', mvdnwind, MSG_down_window, 0,
X        KCTLX | KCTRL | 'P', mvupwind, MSG_up_window, 0,
X        KCTLX | KCTRL | 'R', fileread, MSG_file_read, 0,
X        KCTLX | KCTRL | 'S', filesave, MSG_file_save, 0,
X        KCTLX | KCTRL | 'V', filevisit, MSG_file_visit, 0,
X        KCTLX | KCTRL | 'W', filewrite, MSG_file_write, 0,
X        KCTLX | KCTRL | 'X', swapmark, MSG_swap_dot_and_mark, 0,
X        KCTLX | KCTRL | 'Z', shrinkwind, MSG_shrink_window, 0,
X        KCTLX | '=', showcpos, MSG_display_position, 0,
X        KCTLX | '(', ctlxlp, MSG_start_macro, 0,
X        KCTLX | ')', ctlxrp, MSG_end_macro, 0,
X        KCTLX | '?', help, MSG_help, 0,
X        KCTLX | '0', delwind, MSG_del_window, 0,
X        KCTLX | '1', onlywind, MSG_only_window, 0,
X        KCTLX | '2', splitwind, MSG_split_window, 0,
X        KCTLX | 'B', usebuffer, MSG_use_buffer, 0,
X        KCTLX | 'C', spawncli, MSG_spawn_cli, 0,/* fitz */
X        KCTLX | 'E', ctlxe, MSG_execute_macro, 0,
X        KCTLX | 'G', gotoline, MSG_goto_line, 0,
X        KCTLX | 'I', insertunit, MSG_ins_unit, SMOD | SSIZE | SSRCH | SRPLC,
X        KCTLX | 'K', killbuffer, MSG_kill_buffer, 0,
X        KCTLX | 'L', load_extend, MSG_load_bindings, 0,
X        KCTLX | 'N', nextwind, MSG_forw_window, 0,
X        KCTLX | 'P', prevwind, MSG_back_window, 0,
X        KCTLX | 'V', viewfile, MSG_view_file, 0,/* jam */
X        KCTLX | 'Z', enlargewind, MSG_enlarge_window, 0,
X        KMETA | KCTRL | 'A', asciimode, MSG_ascii_mode, SSRCH | SRPLC, /* pvr */
X        KMETA | KCTRL | 'B', binarymode, MSG_binary_mode, SSRCH | SRPLC, /* pvr */
X        KMETA | KCTRL | 'N', buffername, MSG_buffer_name, 0,
X        KMETA | KCTRL | 'D', decimalmode, MSG_decimal_mode, SSRCH | SRPLC, /* pvr */
X        KMETA | KCTRL | 'E', ebcdicmode, MSG_ebcdic_mode, SSRCH | SRPLC, /* pvr */
X        KMETA | KCTRL | 'H', hexmode, MSG_hex_mode, SSRCH | SRPLC, /* pvr */
X        KMETA | KCTRL | 'K', delbunit, MSG_back_del_unit, SMOD | SSIZE | SSRCH | SRPLC,
X        KMETA | KCTRL | 'O', octalmode, MSG_octal_mode, SSRCH | SRPLC, /* pvr */
X        KMETA | KCTRL | 'V', showversion, MSG_display_version, 0,
X        KMETA | '1', dispsize1, MSG_unit_size1, SSRCH | SRPLC,/* pvr */
X        KMETA | '2', dispsize2, MSG_unit_size2, SSRCH | SRPLC,/* pvr */
X        KMETA | '4', dispsize4, MSG_unit_size4, SSRCH | SRPLC,/* pvr */
X        KMETA | '!', reposition, MSG_reposition_window, 0,
X        KMETA | '.', setmark, MSG_set_mark, 0,
X        KMETA | '>', gotoeob, MSG_goto_eob, SSRCH | SRPLC,
X        KMETA | '<', gotobob, MSG_goto_bob, SSRCH | SRPLC,
X        KMETA | '+', next_buf, MSG_next_buff, 0,
X        KMETA | '-', prev_buf, MSG_prev_buff, 0,
X        KMETA | '%', queryrepl, MSG_query_replace, SMOD,
X        KMETA | '?', wallchart, MSG_display_bindings, 0,
X        KMETA | 'A', autosave, MSG_auto_save, 0,
X        KMETA | 'B', backunit, MSG_back_unit, SSRCH | SRPLC,
X        KMETA | 'C', compare, MSG_compare, 0,
X        KMETA | 'D', delfunit, MSG_forw_del_unit, SMOD | SSIZE | SSRCH | SRPLC,
X        KMETA | 'F', forwunit, MSG_forw_unit, SSRCH | SRPLC,
X        KMETA | 'G', use_buffer, MSG_use_buffer_split, 0,
X        KMETA | 'K', bindtokey, MSG_bind_to_key, 0,
X        KMETA | 'L', linkwind, MSG_link_windows, 0,
X        KMETA | 'O', save_region, MSG_save_region, 0,
X        KMETA | 'P', print, MSG_print, 0,
X        KMETA | 'R', backsearch, MSG_back_search, 0,
X        KMETA | 'S', forwsearch, MSG_forw_search, 0,
X        KMETA | 'T', searchagain, MSG_search_again, 0,
X        KMETA | 'U', file_visit, MSG_file_visit_split, 0,
X        KMETA | 'V', backpage, MSG_back_page, SRPLC,
X        KMETA | 'W', copyregion, MSG_copy_region, 0,
X        KMETA | 'X', extend, MSG_extended_command, 0,
X        KMETA | 'Y', yank_buffer, MSG_yank_buffer, SMOD | SSIZE,
X        KMETA | 'Z', mvupwind, MSG_up_window, 0
X};
X
X#define NKEY    (sizeof(key) / sizeof(key[0]))
X
X/*
X* Symbol table lookup.
X* Return a pointer to the SYMBOL node, or NULL if
X* the symbol is not found.
X*/
XSYMBOL * symlookup (cp)
Xregister char  *cp;
X{
X    register    SYMBOL * sp;
X
X    sp = symbol[symhash (cp)];
X    while (sp != NULL)
X        {
X        if (strcmp (cp, sp -> s_name) == 0)
X            return (sp);
X        sp = sp -> s_symp;
X        }
X    return (NULL);
X}
X
X
X/*
X* Take a string, and compute the symbol table
X* bucket number. This is done by adding all of the characters
X* together, and taking the sum mod NSHASH. The string probably
X* should not contain any GR characters; if it does the "*cp"
X* may get a nagative number on some machines, and the "%"
X* will return a negative number!
X*/
Xint     symhash (cp)
Xregister char  *cp;
X{
X    register int    c;
X    register int    n;
X
X    n = 0;
X    while ((c = *cp++) != 0)
X        n += c;
X    return (n % NSHASH);
X}
X
X
X/*
X* Build initial keymap. The funny keys
X* (commands, odd control characters) are mapped using
X* a big table and calls to "keyadd". The printing characters
X* are done with some do-it-yourself handwaving. The terminal
X* specific keymap initialization code is called at the
X* very end to finish up. All errors are fatal.
X*/
Xvoid keymapinit ()
X{
X    register    SYMBOL * sp;
X    register    KEY * kp;
X    register int    i;
X    register int    hash;
X
X    for (i = 0; i < NKEYS; ++i)
X        binding[i] = NULL;
X    for (kp = &key[0]; kp < &key[NKEY]; ++kp)
X        keyadd (kp -> k_key, kp -> k_funcp, kp -> k_name, kp -> k_modify);
X    keydup (KCTLX | KCTRL | 'G', MSG_abort);
X    keydup (KMETA | KCTRL | 'G', MSG_abort);
X    keydup (0x7F, MSG_back_del_char);
X    keydup (KMETA | 'Q', MSG_quote);
X    keydup (KMETA | 0x7F, MSG_back_del_unit);
X /* 
X  * Should be bound by "tab" already.
X  */
X    if ((sp = symlookup (MSG_ins_self)) == NULL)
X        abort ();
X    for (i = 0x20; i < 0x7F; ++i)
X        {
X        if (binding[i] != NULL)
X            abort ();
X        binding[i] = sp;
X        ++sp -> s_nkey;
X        }
X    ttykeymapinit ();
X}
X
X
X/*
X* Create a new builtin function "name"
X* with function "funcp". If the "new" is a real
X* key, bind it as a side effect. All errors
X* are fatal.
X*/
Xvoid keyadd (new, funcp, name, modify)
Xint     (*funcp) ();
Xchar   *name;
X{
X    register    SYMBOL * sp;
X    register int    hash;
X
X    if ((sp = (SYMBOL *) malloc (sizeof (SYMBOL))) == NULL)
X        abort ();
X    hash = symhash (name);
X    sp -> s_symp = symbol[hash];
X    symbol[hash] = sp;
X    sp -> s_nkey = 0;
X    sp -> s_name = name;
X    sp -> s_funcp = funcp;
X    sp -> s_modify = modify;
X    if (new >= 0)
X        {
X    /* Bind this key.       */
X        if (binding[new] != NULL)
X            abort ();
X        binding[new] = sp;
X        ++sp -> s_nkey;
X        }
X}
X
X/*
X* Bind key "new" to the existing
X* routine "name". If the name cannot be found,
X* or the key is already bound, abort.
X*/
Xvoid keydup (new, name)
Xregister int    new;
Xchar   *name;
X{
X    register    SYMBOL * sp;
X
X    if (binding[new] != NULL || (sp = symlookup (name)) == NULL)
X        {
X        printf (MSG_no_f_tb, name);
X        abort ();
X        }
X    binding[new] = sp;
X    ++sp -> s_nkey;
X}
END_OF_FILE
if test 18972 -ne `wc -c <'symbol.c'`; then
    echo shar: \"'symbol.c'\" unpacked with wrong size!
fi
chmod +x 'symbol.c'
# end of 'symbol.c'
fi
if test -f 'text.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'text.c'\"
else
echo shar: Extracting \"'text.c'\" \(16134 characters\)
sed "s/^X//" >'text.c' <<'END_OF_FILE'
X/*
X*   This file contains all text srtings
X*/
X#include    "def.h"
X
X/* in basic.c */
X    char    MSG_mark_set[]  = "Mark set";
X    char    MSG_no_mark[]   = "No mark in this window";
X    char    MSG_go_b_n[]    = "Goto byte number: ";
X    char    MSG_bad_num[]   = "ERROR: Bad number";
X    char    MSG_lX[]        = "%lX";
X    char    MSG_lO[]        = "%lO";
X    char    MSG_lD[]        = "%lD";
X
X/* in buffer.c */
X    char    MSG_use_b[]     = "Enter name of buffer to goto: ";
X    char    MSG_kill_b[]    = "Enter name of buffer to delete: ";
X    char    MSG_no_del_m[]  = "ERROR: Can't delete 'main'";
X    char    MSG_buf_disp[]  = "ERROR: Buffer is displayed - continue";
X    char    MSG_main[]      = "main";
X    char    MSG_l_buf_h[]   = "S T   Size Buffer           File";
X    char    MSG_l_buf_h1[]  = "- -   ---- ------           ----";
X    char    MSG_no_chg[]    = "Discard changes";
X    char    MSG_yank_b[]    = "Yank from buffer: ";
X    char    MSG_no_buf[]    = "ERROR: no such buffer";
X    char    MSG_no_s_yank[] = "ERROR: can't yank to self!";
X    char    MSG_buf_nam[]   = "Buffer name: ";
X    char    MSG_bad_l[]     = "ERROR: Bad line!";
X    char    MSG_pick[]      = "%s: G(oto) or K(ill) S(ave) ";
X    char    MSG_siz_chg[]   = "Current buffer size may be changed";
X    char    MSG_no_siz_chg[]= "Current buffer size is locked";
X    char    MSG_up_arrow[]  = "^";
X    char    MSG_null[]      = "";
X
X/* in display.c */
X    char    MSG_prn_to[]    = "Print to: ";
X    char    MSG_disp_r_n[]  = "\r\n";
X    char    MSG_11lX[]      = "%11lX:";
X    char    MSG_11lo[]      = "%11lo:";
X    char    MSG_11ld[]      = "%11ld:";
X    char    MSG_03o[]       = "%03o";
X    char    MSG_06o[]       = "%06o";
X    char    MSG_011lo[]     = "%011lo";
X    char    MSG_03u[]       = "%03u";
X    char    MSG_05u[]       = "%05u";
X    char    MSG_010lu[]     = "%010lu";
X    char    MSG_02X[]       = "%02X";
X    char    MSG_04X[]       = "%04X";
X    char    MSG_08lX[]      = "%08lX";
X    char    MSG_prog_name[] = "BEAV";
X    char    MSG_disp_b_lst[]= " Buffer List ";
X    char    MSG_file[]      = "File: ";
X    char    MSG_RO[]        = " [RO]";
X    char    MSG_WL[]        = " [WL]";
X    char    MSG_RW[]        = " [RW]";
X    char    MSG_AU[]        = "[AU]";
X    char    MSG_NOT_AU[]    = "    ";
X    char    MSG_curs_asc[]  = "CURSOR=%08lX,   ASCII";
X    char    MSG_curs_ebc[]  = "CURSOR=%08lX,  EBCDIC";
X    char    MSG_curs_hex[]  = "CURSOR=%08lX,%2X   HEX";
X    char    MSG_curs_bin[]  = "CURSOR=%08lX,%2X   BIN";
X    char    MSG_curs_dec[]  = "CURSOR=%08lu,%2u   DEC";
X    char    MSG_curs_oct[]  = "CURSOR=%08lo,%2o OCTAL";
X    char    MSG_siz_8[]     = " 8 ";
X    char    MSG_siz_16[]    = " 16";
X    char    MSG_siz_32[]    = " 32";
X    char    MSG_siz_null[]  = "   ";
X    char    MSG_int_shift[] = " S%X";
X    char    MSG_mot_shift[] = "  %X";
X    char    MSG_print1[]    = "Writing: %s; Hit any key to quit";
X    char    MSG_print2[]    = "Wrote %s lines";
X
X/*  in ebcdic.c */
X    char    ERR_ebcdic[]    = 
X                "ERROR: Character %s not found in EBCDIC table\n";
X
X/* in echo.c */
X    char    MSG_y_n[]       = "%s [y/n]? ";
X    char    MSG_hex_dig[]   = "0123456789ABCDEF";
X
X/* in extend.c */
X    char    MSG_not_now[]   = "Not now";
X    char    MSG_func[]      = "Function: ";
X    char    MSG_unk_func[]  = "ERROR: Unknown function for binding";
X    char    MSG_cmd_t_ex[]  = "Command to execute: ";
X    char    MSG_unk_ext[]   = "ERROR: Unknown extended command";
X    char    MSG_d_b[]       = 
X                "Display key binding for which key? (hit key now!)";
X    char    MSG_unbd[]      = "%s is unbound";
X    char    MSG_bnd_to[]    = "%s is bound to %s";
X    char    MSG_ins_self[]  = "ins-self";
X    char    MSG_bnd_file[]  = "Binding file: ";
X    char    MSG_bld_wall[]  = "Building help buffer";
X    char    MSG_wall_head[] = "#  Function name                Key binding        Key code";
X    char    MSG_beavrc[]  = "beavrc";
X
X/* in file.c */
X    char    MSG_rd_file[]   = "Read file: ";
X    char    MSG_trash[]     = "#tempbuf#";
X    char    MSG_ins_file[]  = "Insert file: ";
X    char    MSG_not_fnd[]   = "Not found";
X    char    MSG_visit[]     = "Visit file: ";
X    char    MSG_view[]      = "View file (read only): ";
X    char    MSG_buf_ex[]    = "ERROR: Buffer exists";
X    char    MSG_old_buf[]   = "ERROR: Old buffer";
X    char    MSG_cnt_cr[]    = "ERROR: Cannot create buffer";
X    char    MSG_reading[]   = "reading <%s>";
X    char    MSG_read_lx[]   = "Read %s bytes";
X    char    MSG_no_mem_rd[] = 
X    "ERROR: Insufficient memory, read %s bytes; buffer set to read only";
X    char    MSG_wr_file[]   = "Write file: ";
X    char    MSG_no_fn[]     = "ERROR: No file name";
X    char    MSG_bk_err[]    = "ERROR: Backup error, save anyway";
X    char    MSG_writing[]   = "writing <%s>";
X    char    MSG_wrot_1[]    = "Wrote 1 byte";
X    char    MSG_wrot_n[]    = "Wrote %s bytes";
X    char    MSG_fil_nam[]   = "File name: ";
X    char    ERR_parse_fn[]  = 
X            "ERROR: Starting address (%s) must preceede ending address (%s)";
X    char    ERR_addr_neg[]  = "ERROR: Addresses cannot be negative";
X    char    ERR_f_size[]    = 
X            "ERROR: Cannot access past end of file. (file size = %s)";
X
X/* in fileio.c */
X    char    MSG_cnt_wr[]    = "ERROR: Cannot open file for writing";
X    char    MSG_wr_io_er[]  = "ERROR: Write I/O error";
X    char    MSG_rd_er[]     = "ERROR: File read error";
X    char    MSG_bak[]       = ".BAK";
X    char    MSG_backup[]    = "Back-up of %s to %s";
X    char    MSG_back_er[]   = "ERROR: Back-up of %s to %s FAILED !!";
X    char    MSG_back_of[]   = "%s - Back-up of  <%s> to <%s>\n";
X
X/* in format.c */
X    char    hex_str[]       = "%X";
X    char    hex_l_str[]     = "%lX";
X    char    octal_str[]     = "%o";
X    char    octal_l_str[]   = "%lo";
X    char    decimal_str[]   = "%u";
X    char    decimal_l_str[] = "%lu";
X    char    char_str[]      = "%c";
X
X/* in kbd.c */
X    char    MSG_tab[]       = "Tab";
X    char    MSG_ret[]       = "Return";
X    char    MSG_bksp[]      = "Backspace";
X    char    MSG_space[]     = "Space";
X    char    MSG_rubout[]    = "Rubout";
X
X/* in line.c */
X    char    MSG_cnt_alloc[] = "ERROR: Cannot allocate %s bytes for a line";
X    char    MSG_too_m_k[]   = "ERROR: Too many kills";
X
X/* in main.c */
X    char    MSG_ok[]        = "ok";
X    char    MSG_no_mod[]    = "ERROR: Buffer can not be modified";
X    char    MSG_no_s_chg[]  = "ERROR: Buffer size can not be changed";
X    char    MSG_auto_fl[]   = "Doing auto buffer flush";
X    char    MSG_quit[]      = "quit-no-save";
X    char    MSG_st_mac[]    = "Start macro";
X    char    MSG_end_mac[]   = "End macro";
X    char    MSG_num_mod[]   = "Number of modifcations per update: ";
X    char    version[]       = "BEAV, Ver 1.20,  03/07/91";
X
X/*  in random.c */
X    char    MSG_sh_pos[]  = 
X                "Cursor: %s, Mark: %s,  Buffer Size: %s, File Size: %s";
X    char    MSG_sh_pos1[] = 
X                "Cursor: %s, No Mark, Buffer Size: %s, File Size: %s";
X    char    MSG_f_str[]     = ", File: <%s>";
X    char    MSG_3u[]        = "%3u";
X    char    MSG_5u[]        = "%5u";
X    char    MSG_lu[]        = "%lu";
X    char    MSG_lnk[]       = "All windows on buffer <%s> are %s";
X    char    MSG_unlink[]    = "unlinked";
X    char    MSG_link[]      = "linked";
X    char    MSG_bad_key[]   = "ERROR: bad key = ";
X    char    MSG_esc[]       = "Esc,";
X    char    MSG_ctl_x[]     = "Ctl-X,";
X    char    MSG_ctl[]       = "Ctl-";
X    char    MSG_fn[]       = "FN,";
X    char    MSG_key_code[]  = "%s, %s";
X
X/* in region.c */
X    char    MSG_reg_lrg[]   = "ERROR: Mark to cursor is too large";
X    char    MSG_sv_in_b[]   = "Save in buffer: ";
X    char    MSG_sav_slf[]   = "ERROR: Can't save to self!";
X
X/* in search.c */
X    char    MSG_sch_str[]   = " Search String";
X    char    MSG_bsrc_str[]  = "Back Search String";
X    char    MSG_rpl_str[]   = "Replace String";
X    char    MSG_pat_fnd[]   = "Pattern found at %s";
X    char    MSG_no_srch[]   = "ERROR: No last search";
X    char    MSG_fnd_at[]    = 
X                "Found at %s, (R)eplace, (S)kip, (A)ll, (O)ne, (Q)uit.";
X    char    MSG_no_rpl[]    = "No replacements done";
X    char    MSG_1_rpl[]     = "1 replacement done";
X    char    MSG_n_rpl[]     = "%s replacements done";
X    char    MSG_srcing[]    = "Searching at %s, Hit any key to quit.";
X    char    MSG_curs[]      = "%s; Curs = %s, %s Len = %s => ";
X    char    MSG_cmp_end[]   = "Compare reached the end of a buffer";
X    char    MSG_cmp_term[]  = "Compare terminated by user";
X    char    MSG_cmp_dif[]   =
X            "Difference is detected at the two cursor positions";
X    char    MSG_only_2[]    = 
X            "ERROR: There must be exactly two windows displayed to use Compare";
X    char    MSG_cmping[]    = "Comparing at %s, Hit any key to quit.";
X
X/* in spawn.c */
X    char    MSG_shell[]     = "COMSPEC";
X    char    MSG_def_shell[] = "/command.com";
X    char    MSG_pmpt[]      = "PROMPT=[BEAV]";
X    char    MSG_pt[]        = "PROMPT";
X    char    MSG_pme[]       = "PROMPT=";
X
X/* in symbol.c */
X    char    MSG_byte_shift[]        = "display-byte-shift";
X    char    MSG_back_char[]         = "move-back-char";
X    char    MSG_forw_del_char[]     = "delete-forw-char";
X    char    MSG_toggle_swap[]       = "display-swap-order";
X    char    MSG_forw_char[]         = "move-forw-char";
X    char    MSG_abort[]             = "abort-cmd";
X    char    MSG_back_del_char[]     = "delete-back-char";
X    char    MSG_refresh[]           = "refresh-screen";
X    char    MSG_forw_line[]         = "move-forw-line";
X    char    MSG_back_line[]         = "move-back-line";
X    char    MSG_quote[]             = "insert-literally";
X    char    MSG_recall[]            = "recall-srch-string";
X    char    MSG_twiddle[]           = "unit-twiddle";
X    char    MSG_forw_page[]         = "move-forw-page";
X    char    MSG_kill_region[]       = "delete-mark-to-cursor";
X    char    MSG_yank[]              = "yank";
X    char    MSG_down_window[]       = "move-window-down";
X    char    MSG_ins_toggle[]        = "insert-toggle";
X    char    MSG_display_buffers[]   = "buffers-display";
X    char    MSG_exit_flush_all[]    = "quit-save-all";
X    char    MSG_set_file_name[]     = "buffer-set-file-name";
X    char    MSG_file_insert[]       = "insert-file";
X    char    MSG_buf_size_lock[]     = "buffer-size-lock";
X    char    MSG_flush_all[]         = "save-all-buffers";
X    char    MSG_up_window[]         = "move-window-up";
X    char    MSG_file_read[]         = "file-read";
X    char    MSG_file_save[]         = "file-save";
X    char    MSG_file_visit[]        = "file-visit";
X    char    MSG_file_write[]        = "file-write";
X    char    MSG_swap_dot_and_mark[] = "swap-cursor-and-mark";
X    char    MSG_shrink_window[]     = "window-shrink";
X    char    MSG_display_position[]  = "show-position";
X    char    MSG_start_macro[]       = "macro-start";
X    char    MSG_end_macro[]         = "macro-end";
X    char    MSG_help[]              = "binding-for-key";
X    char    MSG_only_window[]       = "window-single";
X    char    MSG_del_window[]        = "window-delete";
X    char    MSG_split_window[]      = "window-split";
X    char    MSG_use_buffer[]        = "change-buffer";
X    char    MSG_spawn_cli[]         = "spawn-shell";
X    char    MSG_execute_macro[]     = "macro-execute";
X    char    MSG_goto_line[]         = "move-to-byte";
X    char    MSG_ins_unit[]          = "insert-unit";
X    char    MSG_kill_buffer[]       = "kill-buffer";
X    char    MSG_load_bindings[]     = "bindings-load";
X    char    MSG_forw_window[]       = "change-window-forw";
X    char    MSG_back_window[]       = "change-window-back";
X    char    MSG_view_file[]         = "file-view";
X    char    MSG_enlarge_window[]    = "window-enlarge";
X    char    MSG_ascii_mode[]        = "display-ascii";
X    char    MSG_binary_mode[]       = "display-binary";
X    char    MSG_buffer_name[]       = "buffer-set-name";
X    char    MSG_decimal_mode[]      = "display-decimal";
X    char    MSG_ebcdic_mode[]       = "display-ebcdic";
X    char    MSG_hex_mode[]          = "display-hex";
X    char    MSG_back_del_unit[]     = "delete-back-unit";
X    char    MSG_octal_mode[]        = "display-octal";
X    char    MSG_display_version[]   = "show-version";
X    char    MSG_unit_size1[]        = "display-bytes";
X    char    MSG_unit_size2[]        = "display-words";
X    char    MSG_unit_size4[]        = "display-double-words";
X    char    MSG_reposition_window[] = "window-reposition";
X    char    MSG_set_mark[]          = "mark-set";
X    char    MSG_goto_eob[]          = "move-to-end";
X    char    MSG_goto_bob[]          = "move-to-begining";
X    char    MSG_next_buff[]         = "change-to-next-buffer";
X    char    MSG_prev_buff[]         = "change-to-prev-buffer";
X    char    MSG_query_replace[]     = "replace";
X    char    MSG_display_bindings[]  = "help";
X    char    MSG_auto_save[]         = "auto-save";
X    char    MSG_back_unit[]         = "move-back-unit";
X    char    MSG_compare[]           = "compare";
X    char    MSG_forw_del_unit[]     = "delete-forw-unit";
X    char    MSG_forw_unit[]         = "move-forw-unit";
X    char    MSG_link_windows[]      = "window-link";
X    char    MSG_print[]             = "print-mark-to-cursor";
X    char    MSG_back_search[]       = "search-back";
X    char    MSG_forw_search[]       = "search-forw";
X    char    MSG_back_page[]         = "move-back-page";
X    char    MSG_copy_region[]       = "copy-mark-to-cursor";
X    char    MSG_extended_command[]  = "extended-command";
X    char    MSG_search_again[]      = "search-again";
X    char    MSG_bind_to_key[]       = "bind-to-key";
X    char    MSG_file_visit_split[]  = "file-visit-split";
X    char    MSG_yank_buffer[]       = "yank-buffer";
X    char    MSG_save_region[]       = "save-mark-to-cursor";
X    char    MSG_use_buffer_split[]  = "move-to-buffer-split";
X    char    MSG_no_f_tb[]           = 
X                "ERROR: Could not find <%s> in look up table\n";
X
X/* in ttykbd.c */
X    char    MSG_sp_key[]    = "%u special keys bound\n";
X
X/* in window.c */
X    char    MSG_no_splt[]   = "ERROR: Cannot split a %s line window";
X    char    MSG_cnt_al_w[]  = "ERROR: Cannot allocate WINDOW block";
X    char    MSG_one_w[]     = "ERROR: Only one window";
X    char    MSG_imp_chg[]   = "ERROR: Impossible change";
X
X#if RUNCHK
X/* in basic.c */
X    char    ERR_bas_1[]     = "ERROR: unknown r_type in basic #1";
X
X/* in display.c */
X    char    ERR_disp_1[]    = "ERROR: unknown r_type in display #1";
X    char    ERR_disp_2[]    = "ERROR: unknown r_type in display #2";
X    char    ERR_disp_3[]    = "ERROR: row less than zero\n";
X    char    ERR_disp_4[]    = "ERROR: row greater then window size\n";
X    char    ERR_disp_5[]    = "ERROR: unknown r_type in display #3";
X    char    ERR_disp_6[]    = "ERROR: unknown r_size in display ";
X/* in line.c */
X    char    ERR_no_alloc[]  = 
X            "ERROR: new line was allocated during read pattern\n";
X    char    ERR_db_dalloc[] = 
X            "ERROR: line was deallocated during read pattern\n";
X    char    ERR_lock[]      = "ERROR: This is size locked, cannot insert.";
X    char    ERR_lock_del[]  = "ERROR: This is size locked, cannot delete.";
X/* in random.c */
X    char    ERR_rnd_1[]     = "ERROR: unknown r_type in random #1";
X    char    ERR_rnd_2[]     = "ERROR: unknown r_size in random #2";
X    char    ERR_rnd_3[]     = "ERROR: unknown r_type in random #3";
X    char    ERR_rnd_4[]     = "ERROR: unknown r_size in random #4";
X    char    MSG_rnd_5[]     = "ERROR: unknown r_size in random #5";
X    char    ERR_rnd_6[]     = "ERROR: unknown r_size in random #6";
X    char    ERR_rnd_7[]     = "ERROR: unknown r_size in random #7";
X/* in search.c */
X    char    ERR_rdpat[] = "ERROR: bad r_type in readpattern\n";
X    char    ERR_mask[]  = "ERROR: size of mask pattern, pat=%d, mask=%d\n";
X    char    ERR_m_cl[]  = "ERROR: in ascii mode mask byte was not cleared\n";
X/* in ttyio.c */
X    char    ERR_bd_pl[] = "ERROR: bad call to putline\n";
X#endif
END_OF_FILE
if test 16134 -ne `wc -c <'text.c'`; then
    echo shar: \"'text.c'\" unpacked with wrong size!
fi
chmod +x 'text.c'
# end of 'text.c'
fi
echo shar: End of archive 4 \(of 10\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
>>>>>>>>>>>>>>>> Peter Reilley ..... pvr@wang.com <<<<<<<<<<<<<<<<<<<<<<<
                     Well, that about says it.

pvr@wang.com (Peter Reilley) (06/06/91)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 5 (of 10)."
# Contents:  buffer.c def.h
# Wrapped by pvr@elf on Thu Mar 14 08:16:47 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'buffer.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'buffer.c'\"
else
echo shar: Extracting \"'buffer.c'\" \(20977 characters\)
sed "s/^X//" >'buffer.c' <<'END_OF_FILE'
X/*
X*       Buffer handling.
X*/
X
X#include    "def.h"
X
Xbool    onebuf ();
Xbool    killablebufs ();
Xbool    _yankbuffer ();
Xchar    next_buf ();
Xbool    bclear ();
Xbool    addline ();
Xvoid    i_to_a ();
Xchar    makelist ();
Xbool    popblist ();
Xchar    listbuffers ();
Xchar    _killbuffer ();
Xbool    _usebuffer ();
X
Xextern  ROW_FMT text_fmt;
Xextern    char    MSG_use_b[];
Xextern    char    MSG_kill_b[];
Xextern    char    MSG_not_fnd[];
Xextern    char    MSG_no_del_m[];
Xextern    char    MSG_buf_disp[];
Xextern    char    MSG_main[];
Xextern    char    MSG_l_buf_h[];
Xextern    char    MSG_l_buf_h1[];
Xextern    char    MSG_no_chg[];
Xextern    char    MSG_yank_b[];
Xextern    char    MSG_no_buf[];
Xextern    char    MSG_no_s_yank[];
Xextern    char    MSG_buf_nam[];
Xextern    char    MSG_bad_l[];
Xextern    char    MSG_pick[];
Xextern    char    MSG_siz_chg[];
Xextern    char    MSG_no_siz_chg[];
Xextern    char    MSG_up_arrow[];
Xextern    char    MSG_null[];
X
X#include    "lintfunc.dec"
X/*
X* Attach a buffer to a window. The
X* values of dot and mark come from the buffer
X* if the use count is 0. Otherwise, they come
X* from some other window.
X*
X* plus hacks for prev/next buffer and use-buffer-split  (jam)
X* functions (like in file.c)
X*/
Xchar    usebuffer ()
X{
X
X    char    bufn[NBUFN];
X    register char   s;
X
X    if ((s = ereply (MSG_use_b, bufn, NBUFN, 0)) != TRUE)
X        return (s);
X    return (_usebuffer (bufn));
X}
X
X/* use buffer, split window first
X*/
Xchar    use_buffer ()
X{
X    char    bufn[NBUFN];
X    register char   s;
X
X    if ((s = ereply (MSG_use_b, bufn, NBUFN, 0)) != TRUE)
X        return (s);
X    splitwind ();
X    return (_usebuffer (bufn));
X}
X
X/* does all the work for changing to a new buffer for use-buffer,
X* use-buffer-split and prev-buff & next-buff
X*/
Xbool _usebuffer (bufn)
Xchar   *bufn;
X{
X    register    BUFFER * bp;
X    register    WINDOW * wp;
X
X    if (strcmp (MSG_kill_b, bufn) == 0)/* hack! */
X        bp = blistp;
X    else
X        if ((bp = bfind (bufn, TRUE)) == NULL)
X            return (FALSE);
X
X    /* if current buffer is special and new buffer is normal */
X    /* set to hex byte mode */
X    if ((curbp == blistp) && (bp != blistp))
X        {
X        dispsize1 ();
X        hexmode (); 
X        }
X        
X    if (--curbp -> b_nwnd == 0)
X        {
X        /* Last use.         */
X        curbp -> b_dotp = curwp -> w_dotp;
X        curbp -> b_doto = curwp -> w_doto;
X        curbp -> b_unit_offset = curwp -> w_unit_offset;/* pvr */
X        curbp -> b_markp = curwp -> w_markp;
X        curbp -> b_marko = curwp -> w_marko;
X        }
X    curbp = bp;                 /* Switch.       */
X    curwp -> w_bufp = bp;
X    curwp -> w_linep = bp -> b_linep;/* For macros, ignored.     */
X    curwp -> w_loff = 0; /* pvr */
X    curwp -> w_flag |= WFMODE | WFFORCE | WFHARD;
X    /* Quite nasty.      */
X    if (bp -> b_nwnd++ == 0)
X        {
X        /* First use.        */
X        curwp -> w_dotp = bp -> b_dotp;
X        curwp -> w_doto = bp -> b_doto;
X        curwp -> w_unit_offset = 0;     /* pvr */
X        curwp -> w_markp = bp -> b_markp;
X        curwp -> w_marko = bp -> b_marko;
X        wind_on_dot (curwp);
X        /* if we are in the funny TEXT mode then goto standard HEX mode */
X        if (R_TYPE(curwp) == TEXT)
X            hexmode ();
X        return (TRUE);
X        }
X    wp = wheadp;                /* Look for old.     */
X    while (wp != NULL)
X        {
X        if (wp != curwp && wp -> w_bufp == bp)
X            {
X            curwp -> w_dotp = wp -> w_dotp;
X            curwp -> w_doto = wp -> w_doto;
X            curwp -> w_unit_offset = wp -> w_unit_offset;/* pvr */
X            curwp -> w_markp = wp -> w_markp;
X            curwp -> w_marko = wp -> w_marko;
X            break;
X            }
X        wp = wp -> w_wndp;
X        }
X    wind_on_dot (curwp);
X    /* if we are in the funny TEXT mode then goto standard HEX mode */
X    if (R_TYPE(curwp) == TEXT)
X        hexmode ();
X    return (TRUE);
X}
X
X
X/*
X* Dispose of a buffer, by name.
X* Ask for the name. Look it up (don't get too
X* upset if it isn't there at all!). Get quite upset
X* if the buffer is being displayed. Clear the buffer (ask
X* if the buffer has been changed). Then free the header
X* line and the buffer header. Bound to "C-X K".
X*/
Xchar    killbuffer ()
X{
X    register char   s;
X    char    bufn[NBUFN];
X
X    if ((s = ereply (MSG_kill_b, bufn, NBUFN, 0)) != TRUE)
X        return (s);
X    if (s = _killbuffer (bufn))
X        writ_echo (okmsg);             /* verbose-ness (jam) */
X    return (s);
X}
X
X
Xchar    _killbuffer (bufn)
Xchar   *bufn;
X{
X    register    BUFFER * bp,
X               *bp1,
X               *bp2;
X    register char   s,
X                    x = 0;
X
X    if ((bp = bfind (bufn, FALSE)) == NULL)
X        {
X        writ_echo (MSG_not_fnd);
X        return (FALSE);
X        }
X
X
X    if (killablebufs (bp))      /* can't kill '?' if no other buffers */
X        {
X        writ_echo (MSG_no_del_m);
X        return (FALSE);
X        }
X
X /* see if the buffer to be killed is in a window */
X    bp1 = bp;
X    if (curbp == blistp && onebuf (bp))/* Hack ! */
X        {
X        next_buf ();
X        onlywind ();
X        update ();
X        }
X
X    if (bp -> b_nwnd > 0)
X        {
X        if ((s = eyesno (MSG_buf_disp)) != TRUE)
X            return (s);
X
X    /* make the current window the only window if it is to die */
X        onlywind ();
X        if (curbp == bp)
X            {
X            next_buf ();
X            if (curbp == bp)
X                x++;
X            }
X        }
X    if ((s = bclear (bp)) != TRUE)/* Blow text away.      */
X        {
X        if (bp1 == blistp)      /* special buffer */
X            curbp = bp1;
X        else
X            if (!x)
X                _usebuffer (bp1 -> b_bname);
X    /* back to original buffer (jam) */
X        return (s);
X        }
X    if (x)
X        {
X        _usebuffer (MSG_main);
X        x++;
X        }
X
X    free ((char *) bp -> b_linep);/* Release header line.         */
X    bp1 = NULL;                 /* Find the header.     */
X    bp2 = bheadp;
X    while (bp2 != bp)
X        {
X        bp1 = bp2;
X        bp2 = bp2 -> b_bufp;
X        }
X    bp2 = bp2 -> b_bufp;        /* Next one in chain.   */
X    if (bp1 == NULL)            /* Unlink it.           */
X        bheadp = bp2;
X    else
X        bp1 -> b_bufp = bp2;
X    free ((char *) bp);         /* Release buffer block         */
X    if (x)
X        update ();
X    if (blistp -> b_nwnd != 0)  /* update buffer display */
X        listbuffers ();
X    return (TRUE);
X}
X
X
X/*
X* Display the buffer list. This is done
X* in two parts. The "makelist" routine figures out
X* the text, and puts it in the buffer whoses header is
X* pointed to by the external "blistp". The "popblist"
X* then pops the data onto the screen. Bound to
X* "C-X C-B".
X*/
Xchar    listbuffers ()
X{
X    register char   s;
X
X    if ((s = makelist ()) != TRUE)
X        return (s);
X    return (popblist ());
X}
X
X/*
X* Pop the special buffer whose
X* buffer header is pointed to by the external
X* variable "blistp" onto the screen. This is used
X* by the "listbuffers" routine (above) and by
X* some other packages. Returns a status.
X*/
Xbool popblist ()
X{
X    register    WINDOW * wp;
X    register    BUFFER * bp;
X
X    if (blistp -> b_nwnd == 0)  /* Not on screen yet.    */
X        {
X        if ((wp = wpopup ()) == NULL)
X            return (FALSE);
X        bp = wp -> w_bufp;
X        if (--bp -> b_nwnd == 0)
X            {
X            bp -> b_dotp = wp -> w_dotp;
X            bp -> b_doto = wp -> w_doto;
X            bp -> b_unit_offset = wp -> w_unit_offset;/* pvr */
X            bp -> b_markp = wp -> w_markp;
X            bp -> b_marko = wp -> w_marko;
X            }
X        wp -> w_bufp = blistp;
X        ++blistp -> b_nwnd;
X        }
X    wp = wheadp;
X    while (wp != NULL)
X        {
X        if (wp -> w_bufp == blistp)
X            {
X            wp -> w_linep = lforw (blistp -> b_linep);
X            wp -> w_loff = 0;
X            wp -> w_dotp = lforw (blistp -> b_linep);
X            wp -> w_doto = 0;
X            wp -> w_unit_offset = 0;
X            wp -> w_markp = NULL;
X            wp -> w_marko = 0;
X            wp -> w_disp_shift = 0;
X            wp -> w_intel_mode = FALSE;
X            wp -> w_fmt_ptr = &text_fmt;
X            wp -> w_flag |= WFMODE | WFHARD;
X            }
X        wp = wp -> w_wndp;
X        }
X    return (TRUE);
X}
X
X/*
X* This routine rebuilds the
X* text in the special secret buffer
X* that holds the buffer list. It is called
X* by the list buffers command. Return TRUE
X* if everything works. Return FALSE if there
X* is an error (if there is no memory).
X*/
Xchar    makelist ()
X{
X    register    char  *cp1;
X    register    char  *cp2;
X    register    int    c;
X    register    BUFFER * bp;
X    register    LINE * lp;
X    register    long   nbytes;
X    register    char   s;
X    char    b[6 + 1];
X    char    line[128];
X
X    blistp -> b_flag &= ~BFCHG; /* Blow away old.    */
X    if ((s = bclear (blistp)) != TRUE)
X        return (s);
X    blistp -> b_flag |= BFVIEW;
X    strcpy (blistp -> b_fname, MSG_up_arrow);
X    if (addline (MSG_l_buf_h) == FALSE
X            || addline (MSG_l_buf_h1) == FALSE)
X        return (FALSE);
X    bp = bheadp;                /* For all buffers   */
X    while (bp != NULL)
X        {
X        cp1 = &line[0];         /* Start at left edge    */
X        if ((bp -> b_flag & BFCHG) != 0)/* "*" if changed    */
X            *cp1++ = '*';
X        else
X            if (bp -> b_flag & BFVIEW)/* jam */
X                *cp1++ = 'R';   /* readonly */
X            else
X                *cp1++ = ' ';
X        *cp1++ = ' ';           /* Gap. */
X        if ((bp -> b_flag & BFBAD) != 0)/* "?" if maybe trashed  */
X            *cp1++ = '?';
X        else
X            *cp1++ = ' ';
X        *cp1++ = ' ';           /* Gap. */
X        nbytes = bp -> b_linep -> l_bp -> l_file_offset +
X                    bp -> b_linep -> l_bp -> l_used;
X        i_to_a (b, 6, (long) nbytes);/* 6 digit buffer size.   */
X        cp2 = &b[0];
X        while ((c = *cp2++) != 0)
X            *cp1++ = c;
X        *cp1++ = ' ';           /* Gap.          */
X        cp2 = &bp -> b_bname[0];/* Buffer name       */
X        while ((c = *cp2++) != 0)
X            *cp1++ = c;
X        *cp1++ = ' ';           /* Gap.          */
X        *cp1++ = ' ';           /* Gap.          */
X        cp2 = &bp -> b_fname[0];/* File name         */
X        if (*cp2 != 0)
X            {
X            while (cp1 < &line[1 + 1 + 1 + 1 + 6 + 1 + NBUFN + 1])
X                *cp1++ = ' ';
X            while ((c = *cp2++) != 0)
X                {
X                if (cp1 < &line[128 - 1])
X                    *cp1++ = c;
X                }
X            }
X        while (cp1 < &line[80])   /* Fill out line to col 80 */
X            *cp1++ = ' ';
X
X        *cp1 = 0;               /* Add to the buffer.    */
X        if (addline (line) == FALSE)
X            return (FALSE);
X        bp = bp -> b_bufp;
X        }
X    return (TRUE);              /* All done      */
X}
X
X
X/*
X* Used above.
X*/
Xvoid i_to_a (buf, width, num)
Xregister char   buf[];
Xregister int    width;
Xregister long   num;
X{
X    buf[width] = 0;             /* End of string.    */
X    while (num >= 10)
X        {
X    /* Conditional digits.   */
X        buf[--width] = (num % 10) + '0';
X        num /= 10;
X        }
X    buf[--width] = num + '0';   /* Always 1 digit.   */
X    while (width != 0)          /* Pad with blanks.  */
X        buf[--width] = ' ';
X}
X
X
X/*
X* The argument "text" points to
X* a string. Append this line to the
X* buffer list buffer. 
X* Return TRUE if it worked and
X* FALSE if you ran out of room.
X*/
Xbool addline (text)
Xchar   *text;
X{
X    register    LINE    * lp;
X    register    int     i, allocsize;
X    register    int     ntext;
X
X    ntext = strlen (text);
X    allocsize = 128;
X
X    if ((lp = lalloc (allocsize)) == NULL)
X        return (FALSE);
X
X    for (i = 0; i < ntext; ++i)
X        lputc (lp, i, text[i]);
X
X    for (; i < allocsize; ++i)     /* fill out line with spaces */
X        lputc (lp, i, ' ');
X
X    blistp -> b_linep -> l_bp -> l_fp = lp;/* Hook onto the end  */
X    lp -> l_bp = blistp -> b_linep -> l_bp;
X    blistp -> b_linep -> l_bp = lp;
X    lp -> l_fp = blistp -> b_linep;
X    lp -> l_size = allocsize;  /* line size is limited to 80 chars */
X    lp -> l_used = allocsize;
X    lp -> l_file_offset = lp -> l_bp -> l_file_offset + lp -> l_bp -> l_used;
X    if (blistp -> b_dotp == blistp -> b_linep)/* If "." is at the end    */
X        blistp -> b_dotp = lp;  /* move it to new line   */
X    return (TRUE);
X}
X
X
X/*
X* Look through the list of
X* buffers. Return TRUE if there
X* are any changed buffers. Special buffers
X* like the buffer list buffer don't count, as
X* they are not in the list. Return FALSE if
X* there are no changed buffers.
X*/
Xbool anycb ()
X{
X    register    BUFFER * bp;
X
X    bp = bheadp;
X    while (bp != NULL)
X        {
X
X        if ((bp -> b_flag & BFCHG) != 0)
X            return (TRUE);
X        bp = bp -> b_bufp;
X        }
X    return (FALSE);
X}
X
X
X/*
X* Search for a buffer, by name.
X* If not found, and the "cflag" is TRUE,
X* create a buffer and put it in the list of
X* all buffers. Return pointer to the BUFFER
X* block for the buffer.
X*/
XBUFFER * bfind (bname, cflag)
Xregister char  *bname;
X{
X    register    BUFFER * bp;
X
X    bp = bheadp;
X    while (bp != NULL)
X        {
X        if (strcmp (bname, bp -> b_bname) == 0)
X            return (bp);
X        bp = bp -> b_bufp;
X        }
X    if (cflag != FALSE && (bp = bcreate (bname)) != NULL)
X        {
X        bp -> b_bufp = bheadp;
X        bheadp = bp;
X        }
X    return (bp);
X}
X
X
X/*
X* Create a buffer, by name.
X* Return a pointer to the BUFFER header
X* block, or NULL if the buffer cannot
X* be created. The BUFFER is not put in the
X* list of all buffers; this is called by
X* "edinit" to create the buffer list
X* buffer.
X*/
XBUFFER * bcreate (bname)
Xregister char  *bname;
X{
X
X    register    BUFFER * bp;
X    register    LINE * lp;
X
X    if ((bp = (BUFFER *) malloc (sizeof (BUFFER))) == NULL)
X        return (NULL);
X    if ((lp = lalloc (0)) == NULL)
X        {
X        free ((char *) bp);
X        return (NULL);
X        }
X    bp -> b_bufp = NULL;
X    bp -> b_dotp = lp;
X    bp -> b_doto = 0;
X    bp -> b_unit_offset = 0;    /* unit offset   pvr */
X    bp -> b_markp = NULL;
X    bp -> b_marko = 0;
X    bp -> b_flag = 0;
X    bp -> b_nwnd = 0;
X    bp -> b_linep = lp;
X    strcpy (bp -> b_fname, MSG_null);
X    strcpy (bp -> b_bname, bname);
X    lp -> l_fp = lp;
X    lp -> l_bp = lp;
X    lp -> l_file_offset = 0;    /* pvr */
X    lp -> l_used = 0;           /* pvr */
X    lp -> l_size = 0;           /* size of zero indicates the header line  pvr 
X                                */
X    return (bp);
X}
X
X
X/*
X* This routine blows away all of the text
X* in a buffer. If the buffer is marked as changed
X* then we ask if it is ok to blow it away; this is
X* to save the user the grief of losing text. The
X* window chain is nearly always wrong if this gets
X* called; the caller must arrange for the updates
X* that are required. Return TRUE if everything
X* looks good.
X*/
Xbool bclear (bp)
Xregister    BUFFER * bp;
X{
X    register    LINE * lp;
X    register char   s;
X
X    if ((bp -> b_flag & BFCHG) != 0/* Changed.       */
X            && (s = eyesno (MSG_no_chg)) != TRUE)
X        return (s);
X    bp -> b_flag &= ~BFCHG;     /* Not changed       */
X    while ((lp = lforw (bp -> b_linep)) != bp -> b_linep)
X        lfree (lp);
X    bp -> b_dotp = bp -> b_linep;/* Fix "."      */
X    bp -> b_doto = 0;
X    bp -> b_unit_offset = 0;    /* pvr */
X    bp -> b_markp = NULL;       /* Invalidate mark  */
X    bp -> b_marko = 0;
X    return (TRUE);
X}
X
X
X/* flip to next buffer in the list, wrap
X* to beginning if required (wrap around)
X* (skips buffers saved  by save-region)  
X*/
Xchar    next_buf ()
X{
X    register    BUFFER * bp;
X
X    bp = curbp;
X    while (TRUE)
X        {
X        if (!(bp = bp -> b_bufp))
X            bp = bheadp;
X        if (!(bp -> b_flag & BFSAV))/* skip save-region buffers */
X            break;
X        }
X    _usebuffer (bp -> b_bname);
X}
X
X
X/* flip to prev buffer in the list, wrap
X* to end if required (wrap around)
X* (does NOT skip buffers saved by save-region)  
X*/
Xchar    prev_buf ()
X{
X    register    BUFFER * sp;
X
X    if ((sp = curbp) == bheadp) /* front of list */
X        for (; sp -> b_bufp; sp = sp -> b_bufp)
X            ;
X    else                        /* cycle around */
X        for (sp = bheadp; sp -> b_bufp; sp = sp -> b_bufp)
X            if (sp -> b_bufp == curbp)
X                break;
X    return (_usebuffer (sp -> b_bname));
X}
X
X
X/* yank a buffer into current buffer
X*/
Xchar    yank_buffer ()
X{
X    register    LINE * lp;
X    register    BUFFER * bp = curbp;
X    register char   s;
X    char    bufn[NBUFN];
X
X    if ((s = ereply (MSG_yank_b, bufn, NBUFN, 0)) != TRUE)
X        return (FALSE);
X    return (_yankbuffer (bufn));
X}
X
X
Xbool _yankbuffer (bufn)
Xchar   *bufn;
X{
X    register    LINE * lp;
X    register    BUFFER * bp = curbp;
X    register int    s;
X
X    if ((bp = bfind (bufn, FALSE)) == NULL)
X        {
X        writ_echo (MSG_no_buf);
X        return (FALSE);
X        }
X    if (strcmp (bp -> b_bname, curbp -> b_bname) == 0)
X        {
X        writ_echo (MSG_no_s_yank);
X        return (FALSE);
X        }
X    lp = lforw (bp -> b_linep);
X    while (TRUE)
X        {
X        for (s = 0; s < lp -> l_used; s++)
X            linsert (1, lp -> l_text[s]);
X
X        if ((lp = lforw (lp)) == bp -> b_linep)
X            {
X            break;
X            }
X        lp = lp -> l_fp;    /* step to next line */
X        }
X    writ_echo (okmsg);
X    return (TRUE);
X}
X
X
Xbool buffername ()
X{
X
X    register    WINDOW * wp;
X    register char  *p;
X    register char   s;
X    char    bname[NBUFN + 1];
X
X    if ((s = ereply (MSG_buf_nam, bname, NBUFN, 0)) == ABORT)
X        return (s);
X    for (p = bname; *p && *p != ' '; p++)
X        ;
X    *p = 0;                     /* no blanks */
X    strcpy (curbp -> b_bname, bname);
X    wp = wheadp;                /* Update mode lines.   */
X    while (wp != NULL)
X        {
X        if (wp -> w_bufp == curbp)
X            wp -> w_flag |= WFMODE;
X        wp = wp -> w_wndp;
X        }
X    if (blistp -> b_nwnd != 0)  /* update buffer display */
X        listbuffers ();
X    return (TRUE);
X}
X
X
X/* any killable buffers around ? (jam)
X*/
Xbool killablebufs (bp)
Xregister    BUFFER * bp;
X{
X    if (strcmp (bp -> b_bname, MSG_main) == 0)/* doomed buffer is 'empty' */
X        if (bheadp == bp)       /* and is only buffer in list */
X            if (bheadp -> b_bufp == 0)/* then there are no killable buffers */
X                return (TRUE);
X    return (FALSE);
X}
X
X
X/* only 1 buffer around ?
X*/
Xbool onebuf (bp)
Xregister    BUFFER * bp;
X{
X    if (strcmp (bp -> b_bname, bheadp -> b_bname) == 0)
X        if (bheadp -> b_bufp == 0)
X            return (TRUE);
X    return (FALSE);
X}
X
X
X/* funky new name; real yukky!!!! (jam) 
X*/
Xvoid funky_name (bname, n)
Xregister char  *bname;
Xint     n;
X{
X    char    num[10];
X    register int    i;
X    register char  *p;
X
X    for (i = 0; i < 10; i++)
X        num[i] = ' ';
X    for (p = bname; *p; p++)
X        *p = 0;
X    *bname++ = '#';
X    i_to_a (num, 6, (long) n + 1);
X    for (p = num; *p; p++)
X        if (*p != ' ')
X            *bname++ = *p;
X    *bname = 0;
X}
X
X
X/* pick a buffer to goto/kill
X*/
X#define BUFFEROFFSET (11)       /* depends on makelist !! */
X
Xbool pickone ()
X{
X    register int    s,
X                    i,
X                    c;
X    register char  *p;
X    register    LINE * lp;
X    char    name[NBUFN + 1];
X    char    buf[3];
X
X    lp = curwp -> w_dotp;       /* get the buffer name from the line */
X
X    i = 0;
X    if (!llength (lp))
X        {
X        writ_echo (MSG_bad_l);
X        return (FALSE);
X        }
X    for (s = BUFFEROFFSET; (c = lgetc (lp, s)) != ' '; s++)
X        {
X        name[i++] = c;
X        if (s >= llength (lp))
X            break;
X        }
X    name[i] = 0;
X    if (!bfind (name, FALSE))
X        {
X        writ_echo (MSG_bad_l);
X        return (FALSE);
X        }
Xloop: 
X    if ((s = ereply (MSG_pick, buf, 2, name)) != TRUE)
X        return (FALSE);
X    if (ISLOWER (buf[0]) != FALSE)
X        buf[0] = TOUPPER (buf[0]);
X    if (buf[0] == 'K')
X        _killbuffer (name);
X    else
X        if (buf[0] == 'G')
X            _usebuffer (name);
X        else
X            if (buf[0] == 'S')
X                {
X                _usebuffer (name);
X            /* goto this buffer, but don't show the user */
X                filesave ();
X                _usebuffer (MSG_kill_b);
X            /* jump back to this window - HACK ! */
X                listbuffers (); /* update the list */
X                }
X            else
X                goto loop;
X    writ_echo (MSG_null);
X    return (TRUE);
X}
X/*
X*   Toggle the buffer size lock bit.
X*/
Xchar bufsizlock ()
X{
X    if (curbp -> b_flag & BFSLOCK)
X    {
X        curbp -> b_flag &= ~BFSLOCK;
X        writ_echo (MSG_siz_chg);
X    }
X    else
X    {
X        if (insert_mode)
X            insert_toggle ();
X        curbp -> b_flag |= BFSLOCK;
X        writ_echo (MSG_no_siz_chg);
X    }
X    return (TRUE);
X}
END_OF_FILE
if test 20977 -ne `wc -c <'buffer.c'`; then
    echo shar: \"'buffer.c'\" unpacked with wrong size!
fi
chmod +x 'buffer.c'
# end of 'buffer.c'
fi
if test -f 'def.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'def.h'\"
else
echo shar: Extracting \"'def.h'\" \(20080 characters\)
sed "s/^X//" >'def.h' <<'END_OF_FILE'
X/*
X *     Common header file.
X *
X * This file is the general header file for all parts
X * of the display editor. It contains all of the
X * general definitions and macros. It also contains some
X * conditional compilation flags. All of the per-system and
X * per-terminal definitions are in special header files.
X * The most common reason to edit this file would be to zap
X * the definition of CVMVAS or BACKUP.
X */
X#define LINT_ARGS   1           /* enable lint type checking */
X#include        "stdio.h"
X
X#define BACKUP  1           /* Make backup file.            */
X#define RUNCHK  1           /* Do additional checking at run time */
X
X#ifndef	uchar
X#define uchar   unsigned    char
X#endif
X
X#ifndef	uint
X#define uint    unsigned    int 
X#endif
X
X#ifndef	ushort
X#define ushort  unsigned    short
X#endif
X
X#ifndef	ulong
X#define ulong   unsigned    long
X#endif
X
X/* these defines are reserved for handling data values from the buffer */
X#define     D8  uchar       /* this had better be a 8 bit quantity */
X#define     D16 ushort      /* this had better be a 16 bit quantity */
X#define     D32 ulong       /* this had better be a 32 bit quantity */
X
X/* this define is reserved for the address of a location in the buffer */
X#define     A32 long        /* this is a 32 bit address into the buffer */
X
X#define     bool char       /* used for boolean values      */
X#define     bits char       /* used for boolean bit flags   */
X
X/*
X *      MS-DOS system header file.
X */
X#if	MSDOS
X#define LARGE   1           /* Large model.         */
X#endif
X#define PCC 1               /* "[]" won't work.     */
X#define GOOD    0           /* Indicate hunkydoryhood   */
X
X/*
X * Macros used by the buffer name making code.
X * Start at the end of the file name, scan to the left
X * until BDC1 (or BDC2, if defined) is reached. The buffer
X * name starts just to the right of that location, and
X * stops at end of string (or at the next BDC3 character,
X * if defined). BDC2 and BDC3 are mainly for VMS.
X */
X#define BDC1    ':'         /* Buffer names.        */
X#define BDC2    '/'         /* Buffer names. jam    */
X
X#ifdef UNIX
X#define PATHCHR ':'
X#define	SEPCHAR '/'
X#else
X#define PATHCHR ';'
X#define	SEPCHAR 0x5c	/* this is a \ char */
X#endif
X
X/*
X *      Digital ANSI terminal header file
X */
X#define GOSLING 0           /* Compile in fancy display.    */
X#ifdef MSDOS
X#define	ANSI	1			/* send ANSI escape codes */
X#endif
X
X#define NROW    25          /* Rows.for boot    */
X#define NCOL    80          /* Columns.         */
X
X#define CUSTOMIZE                       /* compile switch for extended key
X                                           binding in extend.c           */
X#define COSMETIC                        /* cosmetic screen stuff on 
X                                           insert off screen             */
X#ifdef MSDOS
X#define WANG_CHARACTER_SCREEN 0xf0000000L
X#endif
X/*
X * Table sizes, etc.
X */
X#define NSHASH  31          /* Symbol table hash size.      */
X#define NFILEN  80          /* Length, file name.           */
X#define NBUFN   13          /* Length, buffer name.     */
X#define NFILE   12          /* Length, file name.  */ /* krw */
X#define NLINE   80          /* Length, line.      pvr   */
X#define NKBDM   256         /* Length, keyboard macro.      */
X#define NMSG    512         /* Length, message buffer.      */
X#define NPAT    80          /* Length, pattern.             */
X#define HUGE    1000        /* A rather large number.       */
X#define NSRCH   128         /* Undoable search commands.    */
X#define NXNAME  64          /* Length, extended command.    */
X#define NBLOCK  16          /* Line block chunk size        */
X#define MAXPOS  0x7FFFFFFF  /* Maximum positive long value  */
X
X/*
X * Universal.
X */
X#define FALSE   0                       /* False, no, bad, etc.         */
X#define TRUE    1                       /* True, yes, good, etc.        */
X#define ABORT   2                       /* Death, ^G, abort, etc.       */
X
X/*
X * These flag bits keep track of
X * some aspects of the last command.
X * The CFKILL flag controls the clearing versus appending
X * of data in the kill buffer.
X */
X#define CFKILL  0x0002                  /* Last command was a kill      */
X
X/*
X * File I/O.
X */
X#define FIOSUC  0                       /* Success.                     */
X#define FIOFNF  1                       /* File not found.              */
X#define FIOEOF  2                       /* End of file.                 */
X#define FIOERR  3                       /* Error.                       */
X
X/*
X * Directory I/O.
X */
X#define DIOSUC  0                       /* Success.                     */
X#define DIOEOF  1                       /* End of file.                 */
X#define DIOERR  2                       /* Error.                       */
X
X/*
X * Display colors.
X */
X#define CNONE   0                       /* Unknown color.               */
X#define CTEXT   1                       /* Text color.                  */
X#define CMODE   2                       /* Mode line color.             */
X
X/*
X * Flags for "eread".
X */
X#define EFNEW   0x0001                  /* New prompt.                  */
X#define EFAUTO  0x0002                  /* Autocompletion enabled.      */
X#define EFCR    0x0004                  /* Echo CR at end; last read.   */
X
X/*
X * Keys are represented inside using an 11 bit
X * keyboard code. The transformation between the keys on
X * the keyboard and 11 bit code is done by terminal specific
X * code in the "kbd.c" file. The actual character is stored
X * in 8 bits (DEC multinationals work); there is also a control
X * flag KCTRL, a meta flag KMETA, and a control-X flag KCTLX.
X * ASCII control characters are always represented using the
X * KCTRL form. Although the C0 control set is free, it is
X * reserved for C0 controls because it makes the communication
X * between "getkey" and "getkbd" easier. The funny keys get
X * mapped into the C1 control area.
X */
X#define NKEYS   2048                    /* 11 bit code.                 */
X
X#define METACH  0x1B                    /* M- prefix,   Control-[, ESC  */
X#define CTMECH  0x1C                    /* C-M- prefix, Control-\       */
X#define EXITCH  0x1D                    /* Exit level,  Control-]       */
X#define CTRLCH  0x1E                    /* C- prefix,   Control-^       */
X#define HELPCH  0x1F                    /* Help key,    Control-_       */
X
X#define KCHAR   0x00FF                  /* The basic character code.    */
X#define KCTRL   0x0100                  /* Control flag.                */
X#define KMETA   0x0200                  /* Meta flag.                   */
X#define KCTLX   0x0400                  /* Control-X flag.              */
X
X#define KFIRST  0x0080                  /* First special.       fitz    */
X#define KLAST   0x00F3                  /* Last special.                */
X
X#define KRANDOM 0x0080                  /* A "no key" code.             */
X
X/*
X*	This causes the key sequence ESC [ <key> to be delevered as
X*	KCTRL | KMETA | KCTLX | <key>.   This allows VT100 function keys
X*	to be bound. 
X*/
X#define	VT100KEY
X
X/*
X *	These define the column used in the help (wallchart) function 
X */
X#define	HFUNCCOL	3
X#define	HKEY    	32
X#define	HKEYCODE	50
X#define	HENDCOL 	55
X
X/*
X * These flags, and the macros below them,
X * make up a do-it-yourself set of "ctype" macros that
X * understand the DEC multinational set, and let me ask
X * a slightly different set of questions.
X */
X#define _W      0x01                    /* Word.                        */
X#define _U      0x02                    /* Upper case letter.           */
X#define _L      0x04                    /* Lower case letter.           */
X#define _C      0x08                    /* Control.                     */
X
X#define ISCTRL(c)       ((cinfo[(c)]&_C)!=0)
X#define ISUPPER(c)      ((cinfo[(c)]&_U)!=0)
X#define ISLOWER(c)      ((cinfo[(c)]&_L)!=0)
X#define TOUPPER(c)      ((c)-0x20)
X#define TOLOWER(c)      ((c)+0x20)
X
X#define BUF_SIZE(wp)    (wp -> w_bufp -> b_linep -> l_bp -> l_file_offset + \
X                        wp -> w_bufp -> b_linep -> l_bp -> l_used)
X#define BUF_START(wp)   (wp -> w_bufp -> b_linep -> l_fp -> l_file_offset)
X#define DOT_POS(wp)     (wp -> w_dotp -> l_file_offset + wp -> w_doto)
X#define MARK_POS(wp)    (wp -> w_markp -> l_file_offset + wp -> w_marko)
X#define DOT_CHAR(wp)    (wp -> w_dotp -> l_text[wp -> w_doto])
X#define WIND_POS(wp)    (wp -> w_linep -> l_file_offset + wp -> w_loff)
X#define R_TYPE(wp)      (wp -> w_fmt_ptr -> r_type)
X#define R_SIZE(wp)      (wp -> w_fmt_ptr -> r_size)
X#define R_UNITS(wp)     (wp -> w_fmt_ptr -> r_units)
X#define R_BYTES(wp)     (wp -> w_fmt_ptr -> r_bytes)
X#define R_ALIGN(wp)     (wp -> w_fmt_ptr -> r_align)
X#define R_B_PER_U(wp)   (wp -> w_fmt_ptr -> r_b_per_u)
X#define R_CHR_PER_U(wp) (wp -> w_fmt_ptr -> r_chr_per_u)
X#define R_FLAGS(wp)     (wp -> w_fmt_ptr -> r_flags)
X#define R_UNIT_FMT(wp)  (wp -> w_fmt_ptr -> r_unit_fmt)
X#define R_POS_FMT(wp)   (wp -> w_fmt_ptr -> r_pos_fmt)
X#define R_BYTE_FMT(wp)   (wp -> w_fmt_ptr -> r_byte_fmt)
X#define R_POSITIONS(wp) (wp -> w_fmt_ptr -> r_positions)
X
X/*
X * The symbol table links editing functions
X * to names. Entries in the key map point at the symbol
X * table entry. A reference count is kept, but it is
X * probably next to useless right now. The old type code,
X * which was not being used and probably not right
X * anyway, is all gone.
X */
Xtypedef struct  SYMBOL {
X        struct  SYMBOL *s_symp;         /* Hash chain.                  */
X        short   s_nkey;                 /* Count of keys bound here.    */
X        char    *s_name;                /* Name.            */
X        int     (*s_funcp)();           /* Function.                    */
X        bits    s_modify;               /* modify bit */
X}       SYMBOL;
X
X/*
X*   These are the legal values for 's_modify' and 'k_modify'
X*/
X#define SMOD    0x01            /* command modifies the buffer  */
X#define SSIZE   0x02            /* command changes buffer size  */
X#define SSRCH   0x04            /* command valid in search  */
X#define SRPLC   0x08            /* command valid in replace */
X#define SBOUND  0x10            /* key was bound bu user or rc file */
X
X/*
X * There is a window structure allocated for
X * every active display window. The windows are kept in a
X * big list, in top to bottom screen order, with the listhead at
X * "wheadp". Each window contains its own values of dot and mark.
X * The flag field contains some bits that are set by commands
X * to guide redisplay; although this is a bit of a compromise in
X * terms of decoupling, the full blown redisplay is just too
X * expensive to run for every input character.
X */
Xtypedef struct  WINDOW {
X        struct  WINDOW *w_wndp;         /* Next window                  */
X        struct  BUFFER *w_bufp;         /* Buffer displayed in window   */
X        struct  LINE *w_linep;          /* Top line in the window       */
X        int     w_loff;                 /* Offset into line for start pvr  */
X        struct  LINE *w_dotp;           /* Line containing "."          */
X        int     w_doto;                 /* Offset into line for "." */
X        struct  LINE *w_markp;          /* Line containing "mark"       */
X        int     w_marko;                /* Byte offset for "mark"       */
X        char    w_unit_offset;          /* Byte offset for "." into unit pvr */
X        char    w_toprow;               /* Origin 0 top row of window   */
X        char    w_ntrows;               /* # of rows of text in window  */
X        bits    w_flag;                 /* Flags.                       */
X        char    w_disp_shift;           /* Display byte shift; 0-3  pvr */
X        bool    w_intel_mode;           /* Display byte swaped.     pvr */
X        struct  ROW_FMT *w_fmt_ptr;     /* Pointer to display format pvr */
X}       WINDOW;
X
X/*
X * Window flags are set by command processors to
X * tell the display system what has happened to the buffer
X * mapped by the window. Setting "WFHARD" is always a safe thing
X * to do, but it may do more work than is necessary. Always try
X * to set the simplest action that achieves the required update.
X * Because commands set bits in the "w_flag", update will see
X * all change flags, and do the most general one.
X */
X#define WFFORCE 0x01                    /* Force reframe.               */
X#define WFMOVE  0x02                    /* Movement from line to line.  */
X#define WFEDIT  0x04                    /* Editing within a line.       */
X#define WFHARD  0x08                    /* Better to a full display.    */
X#define WFMODE  0x10                    /* Update mode line.        */
X/*
X*   This structure contains how a row is constructed.   pvr
X*/
X
Xtypedef struct  ROW_FMT {
X    uchar   r_type;     /* format type nibbles          */
X    uchar   r_size;     /* format size: must be 0,1,3,7,15, etc */
X    uchar   r_units;    /* number of units per window row: must be 1,2,4,8,16*/
X    uchar   r_bytes;    /* number of bytes per window row: must be 1,2,4,8,16*/
X    uchar   r_align;    /* number of bytes per align row: must be 1,2,4,8,16*/
X    uchar   r_b_per_u;  /* number of bytes per unit: must be 1,2,4,8,16 */
X    uchar   r_chr_per_u; /* displayed chars per unit     */
X    bits    r_flags;    /* flags controlling format     */
X    char    *r_unit_fmt; /* print format for unit */
X    char    *r_pos_fmt; /* print format for buffer position, always a long */
X    char    *r_byte_fmt; /* print format for bytes */
X    uchar   *r_positions; /* list of unit positions   */
X    struct ROW_FMT *r_srch_fmt; /* pointer to search display format */
X    } ROW_FMT;
X
X/* legal values for 'r_size'  (values significant; used as bit mask) pvr */
X
X#define BYTES   0x00        /* Display as byte; 8 bits  */
X#define WORDS   0x01        /* Display as word;    16 bits  */
X#define DWORDS  0x03        /* Display as doubles; 32 bits  */
X
X/* legal values for 'r_type'   pvr */
X#define ASCII   0x10        /* Display as ascii     */
X#define OCTAL   0x20        /* Display as octal values  */
X#define DECIMAL 0x30        /* Display as decimal values    */
X#define HEX     0x40        /* Display as hex values    */
X#define BINARY  0x50        /* Display as binary values */
X#define EBCDIC  0x60        /* Display as ebcdic        */
X#define TEXT    0x70        /* Display as normal text   */
X
X/*
X * Text is kept in buffers. A buffer header, described
X * below, exists for every buffer in the system. The buffers are
X * kept in a big list, so that commands that search for a buffer by
X * name can find the buffer header. There is a safe store for the
X * dot and mark in the header, but this is only valid if the buffer
X * is not being displayed (that is, if "b_nwnd" is 0). The text for
X * the buffer is kept in a circularly linked list of lines, with
X * a pointer to the header line in "b_linep".
X */
Xtypedef struct  BUFFER {
X    bits    buf_type;       /* Type of buffer       */
X    struct  BUFFER *b_bufp; /* Link to next BUFFER          */
X    struct  LINE *b_dotp;   /* Link to "." LINE structure   */
X    int     b_doto;         /* Offset of "." in above LINE  */
X    char    b_unit_offset;  /* Offset into unit for "." pvr */
X    struct  LINE *b_markp;  /* The same as the above two,   */
X    int     b_marko;        /* but for the "mark"       */
X    struct  LINE *b_linep;  /* Link to the header LINE      */
X    char    b_nwnd;         /* Count of windows on buffer   */
X    bits    b_flag;         /* Flags            */
X    A32     b_begin_addr;   /* File address of begining of buffer */
X    A32     b_end_addr;     /* File address of end of buffer */
X    A32     b_file_size;    /* Size of file */
X    char    b_fname[NFILEN]; /* File name                    */
X    char    b_bname[NBUFN];  /* Buffer name                  */
X}   BUFFER;
X
X/* Values for 'buf_type' */
X#define BFILE   0x00            /* Buffer contains a file   */
X#define BDISK   0x01            /* Buffer points to a disk  */
X#define BMEMORY 0x02            /* Buffer points to memory  */
X#define INMEM   0x04            /* File is entirely in memory */
X
X/* Values for 'b_flag' */
X
X#define BFCHG   0x01            /* Changed.         */
X#define BFBAK   0x02                    /* Need to make a backup.       */
X#define BFBAD   0x04                    /* may be trashed alloc error?  */
X#define BFSAV   0x08                    /* saved buffer from save-region */
X#define BFNWL   0x10                    /* append newline to this buffer */
X#define BFVIEW  0x20                    /* read only (jam)               */
X#define BFLINK  0x40            /* Linked mode    pvr        */
X#define BFSLOCK 0x80            /* Lock buffer size   pvr    */
X/*
X * This structure holds the starting position
X * (as a line/offset pair) and the number of characters in a
X * region of a buffer. This makes passing the specification
X * of a region around a little bit easier.
X * There have been some complaints that the short in this
X * structure is wrong; that a long would be more appropriate.
X * I'll await more comments from the folks with the little
X * machines; I have a VAX, and everything fits.
X */
Xtypedef struct  reg {
X        struct  LINE *r_linep;          /* Origin LINE address.         */
X        int     r_offset;               /* Origin LINE offset.          */
X        int     r_size;                 /* Length in characters.        */
X}       REGION;
X
X/*
X * All text is kept in circularly linked
X * lists of "LINE" structures. These begin at the
X * header line (which is the blank line beyond the
X * end of the buffer). This line is pointed to by
X * the "BUFFER". Each line contains a the number of
X * bytes in the line (the "used" size), the size
X * of the text array, and the text. The end of line
X * is not stored as a byte; it's implied. Future
X * additions will include update hints, and a
X * list of marks into the line.
X */
Xtypedef struct  LINE {
X    struct  LINE *l_fp;       /* Link to the next line        */
X    struct  LINE *l_bp;       /* Link to the previous line    */
X    A32     l_file_offset;        /* Offset from begining of file pvr */
X    int     l_size;           /* Allocated size           */
X    int     l_used;           /* Used size            */
X#if     PCC
X    char    l_text[1];        /* A bunch of characters.       */
X#else
X    char    l_text[];         /* A bunch of characters.       */
X#endif
X}      LINE;
X
X/*
X * The rationale behind these macros is that you
X * could (with some editing, like changing the type of a line
X * link from a "LINE *" to a "REFLINE", and fixing the commands
X * like file reading that break the rules) change the actual
X * storage representation of lines to use something fancy on
X * machines with small address spaces.
X */
X#define lforw(lp)       ((lp)->l_fp)
X#define lback(lp)       ((lp)->l_bp)
X#define lgetc(lp, n)    ((lp)->l_text[(n)]&0xFF)
X#define lputc(lp, n, c) ((lp)->l_text[(n)]=(c))
X#define llength(lp)     ((lp)->l_used)
X
X/*
X * Externals.
X */
Xextern  int     thisflag;
Xextern  int     lastflag;
Xextern  int     curgoal;
Xextern  int     epresf;
Xextern  int     sgarbf;
Xextern  WINDOW  *curwp;
Xextern  BUFFER  *curbp;
Xextern  WINDOW  *wheadp;
Xextern  BUFFER  *bheadp;
Xextern  BUFFER  *blistp;
Xextern  short   kbdm[];
Xextern  short   *kbdmip;
Xextern  short   *kbdmop;
Xextern  char    pat[];
Xextern  SYMBOL  *symbol[];
Xextern  SYMBOL  *binding[];
Xextern  BUFFER  *bfind();
Xextern  BUFFER  *bcreate();
Xextern  WINDOW  *wpopup();
Xextern  LINE    *lalloc();
Xextern  int     nrow;
Xextern  int     ncol;
Xextern  char    version[];
Xextern  int     ttrow;
Xextern  int     ttcol;
Xextern  int     tceeol;
Xextern  int     tcinsl;
Xextern  int     tcdell;
Xextern  char    cinfo[];
Xextern  SYMBOL  *symlookup();
Xextern  int     nmsg;
Xextern  int     curmsgf;
Xextern  int     newmsgf;
Xextern  char    msg[];
X 
X/* jam
X */
Xextern  char    *okmsg;
Xextern  int     insert_mode;
Xextern  int     extend_buf;  
Xextern  int     flush_num;
Xextern  int     auto_update;
Xextern  int     flush_count;
Xextern  int     rowb;
Xextern  char    file_off_bad;
X
X/*
X * Standard I/O.
X */
Xextern  char    *malloc();
Xextern  char    *strcpy();
Xextern  char    *strcat();
END_OF_FILE
if test 20080 -ne `wc -c <'def.h'`; then
    echo shar: \"'def.h'\" unpacked with wrong size!
fi
chmod +x 'def.h'
# end of 'def.h'
fi
echo shar: End of archive 5 \(of 10\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
>>>>>>>>>>>>>>>> Peter Reilley ..... pvr@wang.com <<<<<<<<<<<<<<<<<<<<<<<
                     Well, that about says it.

pvr@wang.com (Peter Reilley) (06/06/91)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 6 (of 10)."
# Contents:  file.c search.c
# Wrapped by pvr@elf on Thu Mar 14 08:16:47 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'file.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'file.c'\"
else
echo shar: Extracting \"'file.c'\" \(21304 characters\)
sed "s/^X//" >'file.c' <<'END_OF_FILE'
X/*
X*  File commands.
X*/
X#include        "def.h"
X
Xchar    load_file ();
Xchar    readin ();
Xvoid    makename ();
Xbool    writeout ();
Xbool    parse_f_name ();
X
Xextern    char    MSG_rd_file[];
Xextern    char    MSG_trash[];
Xextern    char    MSG_ins_file[];
Xextern    char    MSG_not_fnd[];
Xextern    char    MSG_visit[];
Xextern    char    MSG_view[];
Xextern    char    MSG_buf_ex[];
Xextern    char    MSG_old_buf[];
Xextern    char    MSG_buf_nam[];
Xextern    char    MSG_cnt_cr[];
Xextern    char    MSG_reading[];
Xextern    char    MSG_read_lx[];
Xextern    char    MSG_no_mem_rd[];
Xextern    char    MSG_wr_file[];
Xextern    char    MSG_no_fn[];
Xextern    char    MSG_bk_err[];
Xextern    char    MSG_writing[];
Xextern    char    MSG_wrot_1[];
Xextern    char    MSG_wrot_n[];
Xextern    char    MSG_fil_nam[];
Xextern    char    MSG_null[];
Xextern    char    ERR_parse_fn[];
Xextern    char    ERR_addr_neg[];
Xextern    char    ERR_f_size[];
X
X#include    "lintfunc.dec"
X
Xstatic int  ughlyflag = FALSE;
X
X/*
X* Read a file into the current
X* buffer. This is really easy; all you do it
X* find the name of the file, and call the standard
X* "read a file into the current buffer" code.
X*/
Xchar    fileread ()
X{
X    register char   s;
X    char    fname[NFILEN];
X    A32     start, end;
X
X    if ((s = ereply (MSG_rd_file, fname, NFILEN, NULL)) != TRUE)
X        return (s);
X    if (parse_f_name (fname, &start, &end))
X    {
X        adjustcase (fname);
X        return (readin (fname, start, end));
X    }
X	return (TRUE);
X}
X
X
X/* insert file into current buffer - use readin, and yank
X*/
Xchar    fileinsert ()
X{
X    register char   s;
X    char    bname[NBUFN],
X            fname[NFILEN];
X    A32     start, end;
X    register char  *trash = MSG_trash;
X
X    strcpy (bname, curbp -> b_bname);/* save current buffer */
X    if ((s = _usebuffer (trash)) == 0)/* temp buffer */
X        return (s);
X    if ((s = ereply (MSG_ins_file, fname, NFILEN, NULL)) != TRUE)
X        return (s);
X    /* if file name and starting and ending addresses are good */ 
X    if (parse_f_name (fname, &start, &end))
X    {
X        adjustcase (fname);
X        if ((s = readin (fname, start, end)) == 0)
X            {
X            writ_echo (MSG_not_fnd);
X            _usebuffer (bname);
X            _killbuffer (trash);
X            return (s);
X            }
X        if ((s = _usebuffer (bname)) == 0)
X            {
X            _killbuffer (trash);
X            return (s);
X            }
X        if ((s = _yankbuffer (trash)) == 0)
X            {
X            _killbuffer (trash);
X            return (s);
X            }
X        writ_echo (okmsg);
X    }
X    else
X    {
X        _usebuffer (bname);
X        _killbuffer (trash);
X        return (FALSE);
X    }
X    if ((s = _killbuffer (trash)) == 0)
X        return (s);
X    wind_on_dot (curwp);
X    return (s);
X}
X
X
X/*
X* Select a file for editing.
X* Look around to see if you can find the
X* fine in another buffer; if you can find it
X* just switch to the buffer. If you cannot find
X* the file, create a new buffer, read in the
X* text, and switch to the new buffer.
X*
X* also various hacked versions for auto load, and 
X* file-vist with auto window split, and readonly (view-file) (jam)
X*/
Xchar    file_visit (f, n, k)
X{
X    char    fname[NFILEN];
X    char    s;
X    A32     start, end;
X    if ((s = ereply (MSG_visit, fname, NFILEN, NULL)) != TRUE)
X        return (s);
X    if (!parse_f_name (fname, &start, &end))
X        return (FALSE);
X
X    splitwind ();
X    return (load_file (fname, start, end));
X}
X
X
X/* like filevisit, only read only
X*/
Xchar    viewfile ()
X{
X    char    fname[NFILEN];
X    char    s;
X    A32     start, end;
X
X    if ((s = ereply (MSG_view, fname, NFILEN, NULL)) != TRUE)
X        return (s);
X    ughlyflag = TRUE;
X    if (!parse_f_name (fname, &start, &end))
X        return (FALSE);
X
X    s = load_file (fname, start, end);
X    if (s)
X        curbp -> b_flag |= BFVIEW;
X    ughlyflag = FALSE;
X    return (s);
X}
X
X
Xchar    filevisit ()
X{
X    char    fname[NFILEN];
X    char    s;
X    A32     start, end;
X
X    if ((s = ereply (MSG_visit, fname, NFILEN, NULL)) != TRUE)
X        return (s);
X    if (!parse_f_name (fname, &start, &end))
X        return (FALSE);
X
X    return (load_file (fname, start, end));
X}
X
X
Xchar    load_file (fname, start, end)       /* jam */
Xchar   *fname;
XA32     start, end;
X{
X    register    BUFFER * bp;
X    register    WINDOW * wp;
X    register    LINE * lp;
X    register int    i;
X    char        s;
X    char        bname[NBUFN];
X    extern int  initial_load;   /* jam */
X    static int  append = 0;
X
X    adjustcase (fname);
X    for (bp = bheadp; bp != NULL; bp = bp -> b_bufp)
X        {
X        if (strcmp (bp -> b_fname, fname) == 0)
X            {
X            if (ughlyflag == TRUE)
X                {
X                writ_echo (MSG_buf_ex);
X                return (FALSE);
X                }
X            if (--curbp -> b_nwnd == 0)
X                {
X                curbp -> buf_type = BFILE;
X                curbp -> b_dotp = curwp -> w_dotp;
X                curbp -> b_doto = curwp -> w_doto;
X                curbp -> b_unit_offset = curwp -> w_unit_offset;
X                curbp -> b_markp = curwp -> w_markp;
X                curbp -> b_marko = curwp -> w_marko;
X                }
X            curbp = bp;
X            curwp -> w_bufp = bp;
X            if (bp -> b_nwnd++ == 0)
X                {
X                curwp -> w_dotp = bp -> b_dotp;
X                curwp -> w_doto = bp -> b_doto;
X                curwp -> w_unit_offset = bp -> b_unit_offset;
X                curwp -> w_markp = bp -> b_markp;
X                curwp -> w_marko = bp -> b_marko;
X                }
X            else
X                {
X                wp = wheadp;
X                while (wp != NULL)
X                    {
X                    if (wp != curwp && wp -> w_bufp == bp)
X                        {
X                        curwp -> w_dotp = wp -> w_dotp;
X                        curwp -> w_doto = wp -> w_doto;
X                        curwp -> w_unit_offset = wp -> w_unit_offset;
X                        curwp -> w_markp = wp -> w_markp;
X                        curwp -> w_marko = wp -> w_marko;
X                        break;
X                        }
X                    wp = wp -> w_wndp;
X                    }
X                }
X            lp = curwp -> w_dotp;
X            i = curwp -> w_ntrows / 2;
X            while (i-- && lback (lp) != curbp -> b_linep)
X                lp = lback (lp);
X            curwp -> w_linep = lp;
X            curwp -> w_flag |= WFMODE | WFHARD;
X            if (kbdmop == NULL)
X                {
X                writ_echo (MSG_old_buf);
X                }
X            return (TRUE);
X            }
X        }
X
X    makename (bname, fname);    /* New buffer name.     */
X    while ((bp = bfind (bname, FALSE)) != NULL)
X        {
X        if (initial_load)       /* patch old name */
X            {
X            funky_name (bname, append++);
X            bp = NULL;
X            break;
X            }
X        s = ereply (MSG_buf_nam, bname, NBUFN, NULL);
X        if (s == ABORT)         /* ^G to just quit      */
X            return (s);
X        if (strcmp (bp -> b_bname, bname) == 0 || s == FALSE)
X            {
X        /* CR to clobber it     */
X            makename (bname, fname);
X            break;
X            }
X        }
X    if (bp == NULL && (bp = bfind (bname, TRUE)) == NULL)
X        {
X        writ_echo (MSG_cnt_cr);
X        return (FALSE);
X        }
X    if (--curbp -> b_nwnd == 0)
X        {
X        /* Undisplay.           */
X        curbp -> buf_type = BFILE;
X        curbp -> b_dotp = curwp -> w_dotp;
X        curbp -> b_doto = curwp -> w_doto;
X        curbp -> b_unit_offset = curwp -> w_unit_offset;
X        curbp -> b_markp = curwp -> w_markp;
X        curbp -> b_marko = curwp -> w_marko;
X        }
X    curbp = bp;                 /* Switch to it.        */
X    curwp -> w_bufp = bp;
X    curbp -> b_nwnd++;
X    return (readin (fname, start, end));    /* Read it in.          */
X}
X
X
X/*
X* Read the file "fname" into the current buffer.
X* Make all of the text in the buffer go away, after checking
X* for unsaved changes. This is called by the "read" command, the
X* "visit" command, and the mainline (for "beav file"). If the
X* BACKUP conditional is set, then this routine also does the read
X* end of backup processing. The BFBAK flag, if set in a buffer,
X* says that a backup should be taken. It is set when a file is
X* read in, but not on a new file (you don't need to make a backup
X* copy of nothing). Return a standard status. Print a summary
X* (lines read, error message) out as well.
X*/
Xchar    readin (fname, start, end)
Xchar    fname[];
XA32     start, end;
X{
X    register    LINE * lp1;
X    register    LINE * lp2;
X    register    char   i;
X    register    WINDOW * wp;
X    register    BUFFER * bp;
X    register    char   s, m;
X    long        byte_cnt;
X    char        line[NLINE];
X    int         num_chars, req_chars;
X    char        buf[80], buf1[80];
X    A32         temp;
X
X    m = TRUE;
X    byte_cnt = 0;
X    bp = curbp;                 /* Cheap.               */
X    if ((s = bclear (bp)) != TRUE)/* Might be old.        */
X        return (s);
X#if     BACKUP
X    bp -> b_flag &= ~(BFCHG | BFBAK);/* No change, backup.   */
X#else
X    bp -> b_flag &= ~BFCHG;     /* No change.           */
X#endif
X    if ((start == 0L) && (end == MAXPOS))
X        strcpy (bp -> b_fname, fname);
X    else
X        strcpy (bp -> b_fname, MSG_null);
X    if ((s = ffropen (fname)) == FIOERR || s == FIOFNF)/* jam */
X        goto out;
X    bp -> b_file_size = file_len ();  /* get the file lenth */
X    sprintf (buf, MSG_reading, fname);/* jam */
X    writ_echo (buf);
X    temp = ffseek (start);
X    if (temp != start)
X    {
X        sprintf (buf1, ERR_f_size, R_POS_FMT(curwp));
X        sprintf (buf, buf1, temp);
X        writ_echo (buf);
X        return (FALSE);
X    }
X    /* only read the requested number of characters */
X    if ((end - start) > NLINE)
X        req_chars = NLINE;
X    else
X        req_chars = (int)(end - start);
X
X    while ((s = ffgetline (line, req_chars, &num_chars)) == FIOSUC)
X        {
X        if ((lp1 = lalloc(num_chars)) == NULL)
X            {
X            bp -> b_flag |= BFVIEW; /* if no memory set to read only mode */ 
X            m = FALSE;          /* flag memory allocation error */
X            break;          
X            }
X        /* this code breaks rules for knowing how lines * are stored and linked
X        together, oh well */
X        lp2 = lback (curbp -> b_linep);
X        lp2 -> l_fp = lp1;
X        lp1 -> l_fp = curbp -> b_linep;
X        lp1 -> l_bp = lp2;
X        curbp -> b_linep -> l_bp = lp1;
X        for (i = 0; i < num_chars; ++i)
X            lputc (lp1, i, line[i]);
X        lp1 -> l_used = num_chars;      /* number of bytes in this line */
X        lp1 -> l_file_offset = byte_cnt;   /* file offset from begining */
X        byte_cnt += (long) num_chars;   /* number of bytes read in    */
X        start += (long) num_chars;
X        if (end <= start)
X            break;
X        /* stop reading after the requested number of characters */
X        if (end < start + req_chars)
X            {
X            req_chars = end - start;
X            }
X        }
X    ffclose ();                 /* Ignore errors.       */
X    if (s == FIOEOF && kbdmop == NULL)
X        {
X        /* Don't zap an error.   */
X        sprintf (buf1, MSG_read_lx, R_POS_FMT(curwp));
X        sprintf (buf, buf1, byte_cnt);
X        writ_echo (buf);
X        }
X    if (m == FALSE && kbdmop == NULL)
X        {
X        /* Don't zap an error.   */
X        sprintf (buf1, MSG_no_mem_rd, R_POS_FMT(curwp));
X        sprintf (buf, buf1, byte_cnt);
X        writ_echo (buf);
X        }
X
X#if     BACKUP
X    curbp -> b_flag |= BFBAK;   /* Need a backup.       */
X#endif
Xout: 
X    for (wp = wheadp; wp != NULL; wp = wp -> w_wndp)
X        {
X        if (wp -> w_bufp == curbp)
X            {
X            wp -> w_linep = lforw (curbp -> b_linep);
X            wp -> w_dotp = lforw (curbp -> b_linep);
X            wp -> w_doto = 0;
X            wp -> w_unit_offset = 0;
X            wp -> w_markp = NULL;
X            wp -> w_marko = 0;
X            wp -> w_flag |= WFMODE | WFHARD;
X            }
X        }
X    if (s == FIOERR || s == FIOFNF)/* False if error.      */
X        return (FALSE);
X /* so tell yank-buffer about it */
X    if (blistp -> b_nwnd != 0)  /* update buffer display */
X        listbuffers ();
X    return (TRUE);
X}
X
X
X/*
X* Take a file name, and from it
X* fabricate a buffer name. This routine knows
X* about the syntax of file names on the target system.
X* BDC1         left scan delimiter.
X* BDC2         optional second left scan delimiter.
X* BDC3         optional right scan delimiter.
X*/
Xvoid makename (bname, fname)
Xchar    bname[];
Xchar    fname[];
X{
X    register char  *cp1;
X    register char  *cp2;
X
X    cp1 = &fname[0];
X    while (*cp1 != 0)
X        ++cp1;
X#ifdef  BDC2
X    while (cp1 != &fname[0] && cp1[-1] != BDC1 && cp1[-1] != BDC2)
X        --cp1;
X#else
X    while (cp1 != &fname[0] && cp1[-1] != BDC1)
X        --cp1;
X#endif
X    cp2 = &bname[0];
X#ifdef  BDC3
X    while (cp2 != &bname[NBUFN - 1] && *cp1 != 0 && *cp1 != BDC3)
X        *cp2++ = *cp1++;
X#else
X    while (cp2 != &bname[NBUFN - 1] && *cp1 != 0)
X        *cp2++ = *cp1++;
X#endif
X    *cp2 = 0;
X}
X
X
X/*
X* Ask for a file name, and write the
X* contents of the current buffer to that file.
X* Update the remembered file name and clear the
X* buffer changed flag. This handling of file names
X* is different from the earlier versions, and
X* is more compatable with Gosling EMACS than
X* with ITS EMACS.
X*/
Xchar    filewrite ()
X{
X    register    WINDOW * wp;
X    register char   s;
X    char    fname[NFILEN];
X    A32     start, end;
X
X    if ((s = ereply (MSG_wr_file, fname, NFILEN, NULL)) != TRUE)
X        return (s);
X    if (!parse_f_name (fname, &start, &end))
X        return (FALSE);
X
X    adjustcase (fname);
X    if ((s = writeout (fname, start, end)) == TRUE)
X        {
X        strcpy (curbp -> b_fname, fname);
X        curbp -> b_flag &= ~BFCHG;
X        wp = wheadp;            /* Update mode lines.   */
X        while (wp != NULL)
X            {
X            if (wp -> w_bufp == curbp)
X                wp -> w_flag |= WFMODE;
X            wp = wp -> w_wndp;
X            }
X        }
X
X#if     BACKUP
X    curbp -> b_flag &= ~BFBAK;  /* No backup.           */
X#endif
X    return (s);
X}
X
X
X/*
X* Save the contents of the current buffer back into
X* its associated file. Do nothing if there have been no changes
X* (is this a bug, or a feature). Error if there is no remembered
X* file name. If this is the first write since the read or visit,
X* thet a backup copy of the file is made.
X*/
Xchar    filesave ()
X{
X    register    WINDOW * wp;
X    register char   s;
X
X    if ((curbp -> b_flag & BFCHG) == 0)/* Return, no changes.  */
X        return (TRUE);
X    if (curbp -> b_fname[0] == 0)/* Must have a name.    */
X        {
X        if (!(curbp -> b_flag & BFSAV))/* yanked buffer */
X            {
X            writ_echo (MSG_no_fn);
X            }
X        return (FALSE);
X        }
X#if     BACKUP
X    if ((curbp -> b_flag & BFBAK) != 0)
X        {
X        s = fbackupfile (curbp -> b_fname);
X        if (s == ABORT)         /* Hard error.          */
X            return (s);
X        if (s == FALSE          /* Softer error.        */
X                && (s = eyesno (MSG_bk_err)) != TRUE)
X            return (s);
X        }
X
X#endif
X    if ((s = writeout (curbp -> b_fname, 0L, MAXPOS)) == TRUE)
X        {
X        curbp -> b_flag &= ~BFCHG;/* No change.           */
X        curbp -> b_flag &= ~BFBAD;/* if it was trashed, forget it now */
X        wp = wheadp;            /* Update mode lines.   */
X        while (wp != NULL)
X            {
X            if (wp -> w_bufp == curbp)
X                wp -> w_flag |= WFMODE;
X            wp = wp -> w_wndp;
X            }
X        }
X
X#if     BACKUP
X    curbp -> b_flag &= ~BFBAK;  /* No backup.           */
X#endif
X    return (s);
X}
X
X/*
X* This function performs the details of file
X* writing. Uses the file management routines in the
X* "fileio.c" package. The number of lines written is
X* displayed. Sadly, it looks inside a LINE; provide
X* a macro for this. Most of the grief is error
X* checking of some sort.
X*/
Xbool writeout (fn, start, end)
Xchar   *fn;
XA32     start, end;
X{
X    register    int    s, num_chars;
X    register    LINE * lp;
X    register    long   nbytes;
X    char        buf[80], buf1[80];
X    A32         temp;
X
X    if ((s = ffwopen (fn)) != FIOSUC)/* Open writes message. */
X        return (FALSE);
X    temp = ffseek (start);
X    if (temp != start)
X    {
X        sprintf (buf1, ERR_f_size, R_POS_FMT(curwp));
X        sprintf (buf, buf1, temp);
X        writ_echo (buf);
X        return (FALSE);
X    }
X    sprintf (buf, MSG_writing, fn);/* jam */
X    writ_echo (buf);
X
X	/* insure that the help screen reflects the latest bindings */
X	if (curbp == blistp)
X		wallchart ();
X
X    lp = lforw (curbp -> b_linep);/* First line. */
X    nbytes = 0;                  /* Number of bytes.  */
X    temp = end - start;         /* number of bytes to write */
X    while (lp != curbp -> b_linep)
X        {
X		if (curbp == blistp)
X		{
X			/* special list buffer */
X			num_chars = HENDCOL;	/* limit line length */
X			lp -> l_text[num_chars - 1] = '\n';
X		}
X		else
X		{
X			/* standard buffer */
X	        if (nbytes + (long)llength (lp) > temp)
X    	        num_chars = (int)(temp - nbytes);
X        	else
X            	num_chars = llength (lp);   
X		}
X        if ((s = ffputline (&lp -> l_text[0], num_chars)) != FIOSUC)
X            break;
X        nbytes += num_chars;
X        if (temp <= nbytes)
X            break;
X        lp = lforw (lp);
X        }
X    if (s == FIOSUC)
X        {
X    /* No write error. */
X        s = ffclose ();
X        if (s == FIOSUC && kbdmop == NULL)
X            {
X            if (nbytes == 1)
X                {
X                writ_echo (MSG_wrot_1);
X                }
X            else
X                {
X                sprintf (buf1, MSG_wrot_n, R_POS_FMT(curwp));
X                sprintf (buf, buf1, (long) nbytes);
X                writ_echo (buf);
X                }
X            }
X        }
X    else                        /* Ignore close error   */
X        ffclose ();             /* if a write error.    */
X    if (s != FIOSUC)            /* Some sort of error.  */
X        return (FALSE);
X    curbp -> b_file_size = nbytes;  /* update file size */
X    if (blistp -> b_nwnd != 0)  /* update buffer display */
X        listbuffers ();
X    return (TRUE);
X}
X
X/*
X* The command allows the user
X* to modify the file name associated with
X* the current buffer. It is like the "f" command
X* in UNIX "ed". The operation is simple; just zap
X* the name in the BUFFER structure, and mark the windows
X* as needing an update. You can type a blank line at the
X* prompt if you wish.
X*/
Xchar    filename ()
X{
X    register    WINDOW * wp;
X    register char   s;
X    char    fname[NFILEN];
X    A32     start, end;
X
X    if ((s = ereply (MSG_fil_nam, fname, NFILEN, NULL)) == ABORT)
X        return (s);
X    if (!parse_f_name (fname, &start, &end))
X        return (FALSE);
X
X    adjustcase (fname);
X    curbp -> b_flag |= BFCHG;   /* jam - on name change, set modify */
X    BUF_START(curwp) = start;
X    l_fix_up (NULL);    /* adjust file offsets from first line */
X    strcpy (curbp -> b_fname, fname);/* Fix name.            */
X    wp = wheadp;                /* Update mode lines.   */
X    while (wp != NULL)
X        {
X        if (wp -> w_bufp == curbp)
X            wp -> w_flag |= WFMODE;
X        wp = wp -> w_wndp;
X        }
X#if     BACKUP
X    curbp -> b_flag &= ~BFBAK;  /* No backup.           */
X#endif
X    return (TRUE);
X}
X
X/*
X*   Get the length parameters that were entered with the file name.
X*   There can be the file name only.
X*   There can be a file name and a starting position.
X*   There can be a name a starting position and an ending position.
X*   There can be a name a starting position and a length.
X*
X*   input:
X*       fn      pointer to file name string to parse.
X*
X*   output:
X*       fn      pointer to null terminated file name.
X*       start   pointer to the starting point in file (default = 0)
X*       end     pointer to the end point in file (default = -1)
X*       return  FALSE if file name or addresses are bad.
X*/
Xbool    parse_f_name (fn, start, end)
Xchar    *fn;
XA32     *start, *end;
X    {
X    char    buf[NFILEN], buf1[80], fmt[10];
X    int     i_cnt;
X    A32     temp;
X
X    /* build up format string according to the current screen format */ 
X    sprintf (fmt, "%s %s %s", "%s", R_POS_FMT(curwp), R_POS_FMT(curwp));
X
X    *start = 0L;
X    *end = MAXPOS;
X    sscanf (fn, fmt, buf, start, end);
X
X    if (*end != MAXPOS)
X        {
X        for (i_cnt = strlen (fn) - 1; i_cnt >= 0; i_cnt--)
X            {
X            if (fn[i_cnt] == '+')
X                {
X                *end += *start;
X                break;
X                }
X            }
X        }
X    /* start should preceed end */
X    if (*start > *end)
X        {
X        sprintf (buf1, ERR_parse_fn, R_POS_FMT(curwp), R_POS_FMT(curwp));
X        sprintf (buf, buf1, *start, *end);
X        writ_echo (buf);
X        return (FALSE);
X        }
X
X    /* error if addresses are negative */
X    if ((*start < 0) || (*end < 0))
X    {   
X        writ_echo (ERR_addr_neg);
X        return (FALSE);
X    }
X
X    /* deposit null terminated file name */
X    strcpy (fn, buf);
X    return (TRUE);
X    }
END_OF_FILE
if test 21304 -ne `wc -c <'file.c'`; then
    echo shar: \"'file.c'\" unpacked with wrong size!
fi
chmod +x 'file.c'
# end of 'file.c'
fi
if test -f 'search.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'search.c'\"
else
echo shar: Extracting \"'search.c'\" \(30053 characters\)
sed "s/^X//" >'search.c' <<'END_OF_FILE'
X/*
X*       Search commands.
X* The functions in this file implement the
X* search commands (both plain and incremental searches
X* are supported) and the query-replace command.
X*/
X#include    "def.h"
X
Xchar    replaceit ();
Xchar    forwsrch ();
Xchar    backsrch ();
Xchar    readpattern ();
Xvoid    next_pat ();
X
Xextern    char    MSG_sch_str[];
Xextern    char    MSG_bsrc_str[];
Xextern    char    MSG_rpl_str[];
Xextern    char    MSG_pat_fnd[];
Xextern    char    MSG_no_srch[];
Xextern    char    MSG_fnd_at[];
Xextern    char    MSG_no_rpl[];
Xextern    char    MSG_1_rpl[];
Xextern    char    MSG_n_rpl[];
Xextern    char    MSG_srcing[];
Xextern    char    MSG_curs[];
Xextern    char    MSG_cmp_end[];
Xextern    char    MSG_cmp_term[];
Xextern    char    MSG_cmp_dif[];
Xextern    char    MSG_only_2[];
Xextern    char    MSG_cmping[];
Xextern    char    MSG_not_fnd[];
X#if RUNCHK
Xextern    char    ERR_rdpat[];
Xextern    char    ERR_mask[];
Xextern    char    ERR_m_cl[];
X#endif
X
X#include    "lintfunc.dec"
X#define CCHR(x)     ((x)-'@')
X
X#define SRCH_BEGIN  (0)         /* Search sub-codes.    */
X#define SRCH_FORW   (-1)
X#define SRCH_BACK   (-2)
X#define SRCH_PREV   (-3)
X#define SRCH_NEXT   (-4)
X#define SRCH_NOPR   (-5)
X#define SRCH_ACCM   (-6)
X
Xtypedef struct
X{
X    int     s_code;
X            LINE * s_dotp;
X    short   s_doto;
X}SRCHCOM;
X
X#define MAX_PAT 260
X
Xextern  ROW_FMT hex_s_8_fmt;
Xextern  ROW_FMT ascii_s_fmt;
X
Xbool    recall_flag = FALSE;
Xbool    read_pat_mode = FALSE;
Xbool    srch_mode = FALSE;
Xbool    rplc_mode = FALSE;
Xbool    dont_repeat = FALSE;    /* used to prevent toggling commands from */
X                                /* failing in read_pattern */
Xstatic  char    srch_patb[MAX_PAT];
Xstatic  char    srch_maskb[MAX_PAT];
Xstatic  char    rplc_patb[MAX_PAT];
Xstatic  char    rplc_maskb[MAX_PAT];
X
Xstatic  LINE    *srch_pat = (LINE *)srch_patb;
Xstatic  LINE    *srch_mask = (LINE *)srch_maskb;
Xstatic  LINE    *cur_pat;
Xstatic  LINE    *cur_mask;
Xstatic  LINE    *rplc_pat = (LINE *)rplc_patb;
Xstatic  LINE    *rplc_mask = (LINE *)rplc_maskb;
X
Xstatic  int     old_srch_pat_size = 0;/* for pattern recall */
Xstatic  int     old_rplc_pat_size = 0;
Xstatic  ROW_FMT *old_fmt = &hex_s_8_fmt;
X
X        char    *cur_prompt;
X
Xstatic  SRCHCOM cmds[NSRCH];
Xstatic int  cip;
X
Xint     srch_lastdir = SRCH_NOPR;/* Last search flags.   */
X
X/*
X* Search forward.
X* Get a search string from the user, and search for it,
X* starting at ".". If found, "." gets moved to the
X* first matched character, and display does all the hard stuff.
X* If not found, it just prints a message.
X*/
Xchar    forwsearch ()
X{
X    register char   s;
X    char    buf[80], buf1[30];
X
X    srch_mode = TRUE;
X    rplc_mode = FALSE;
X    cur_prompt = MSG_sch_str;
X    if ((s = readpattern ()) != TRUE)
X        {
X        srch_mode = FALSE;
X        eerase ();  /* clear message line */
X        return (s);
X        }
X    if (forwsrch () == FALSE)
X        {
X        writ_echo (MSG_not_fnd);
X        srch_mode = FALSE;
X        return (FALSE);
X        }
X    srch_lastdir = SRCH_FORW;
X    curwp -> w_flag |= WFMODE;  /* update mode line */
X    curwp -> w_unit_offset = 0;
X    /* build format */
X    sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
X    sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
X                curwp -> w_doto);
X    writ_echo (buf);
X    srch_mode = FALSE;
X    return (TRUE);
X}
X
X
X/*
X* Reverse search.
X* Get a search string from the  user, and search, starting at "."
X* and proceeding toward the front of the buffer. If found "." is left
X* pointing at the first character of the pattern [the last character that
X* was matched].
X*/
Xchar    backsearch ()
X{
X    register char   s;
X    char    buf[80], buf1[30];
X
X    srch_mode = TRUE;
X    rplc_mode = FALSE;
X    cur_prompt = MSG_bsrc_str;
X    if ((s = readpattern ()) != TRUE)
X        {
X        srch_mode = FALSE;
X        eerase ();  /* clear message line */
X        return (s);
X        }
X    if (backsrch () == FALSE)
X        {
X        writ_echo (MSG_not_fnd);
X        srch_mode = FALSE;
X        return (FALSE);
X        }
X    srch_lastdir = SRCH_BACK;
X    curwp -> w_flag |= WFMODE;  /* update mode line */
X    curwp -> w_unit_offset = 0;
X    sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
X    sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
X                curwp -> w_doto);
X    writ_echo (buf);
X    srch_mode = FALSE;
X    return (TRUE);
X}
X
X
X/* 
X* Search again, using the same search string
X* and direction as the last search command. The direction
X* has been saved in "srch_lastdir", so you know which way
X* to go.
X*/
Xchar    searchagain ()
X{
X    char    buf[80], buf1[30];
X    long    dot_pos;
X    srch_mode = TRUE;
X    rplc_mode = FALSE;
X
X    dot_pos = DOT_POS(curwp);
X    if (srch_lastdir == SRCH_FORW)
X        {
X        /* advance one unit so we don't find the same thing again */
X        move_ptr (curwp, dot_pos + 1, TRUE, FALSE, FALSE);
X        if (forwsrch () == FALSE)
X            {    /* go back to orig pt */
X            move_ptr (curwp, dot_pos, TRUE, FALSE, FALSE);
X            writ_echo (MSG_not_fnd);
X            srch_mode = FALSE;
X            return (FALSE);
X            }
X        curwp -> w_flag |= WFMODE;  /* update mode line */
X        curwp -> w_unit_offset = 0;
X        sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
X        sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
X                    curwp -> w_doto);
X        writ_echo (buf);
X        srch_mode = FALSE;
X        return (TRUE);
X        }
X    if (srch_lastdir == SRCH_BACK)
X        {
X        /* step back one unit so we don't find the same thing again */
X        move_ptr (curwp, dot_pos - 1, TRUE, FALSE, FALSE);
X        if (backsrch () == FALSE)
X            {    /* go back to orig pt */
X            move_ptr (curwp, dot_pos, TRUE, FALSE, FALSE);
X            writ_echo (MSG_not_fnd);
X            srch_mode = FALSE;
X            return (FALSE);
X            }
X        curwp -> w_flag |= WFMODE;  /* update mode line */
X        curwp -> w_unit_offset = 0;
X        sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
X        sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
X                    curwp -> w_doto);
X        writ_echo (buf);
X        srch_mode = FALSE;
X        return (TRUE);
X        }
X    writ_echo (MSG_no_srch);
X    srch_mode = FALSE;
X    return (FALSE);
X}
X
X
X/*
X* Query Replace.
X*   Replace strings selectively.  Does a search and replace operation.
X*   A space or a comma replaces the string, a period replaces and quits,
X*   an n doesn't replace, a C-G quits.
X* (note typical hack to add a function with minimal code) 
X*/
Xchar    queryrepl (f, n, k)
X{
X
X    register char   s;
X
X    srch_mode = FALSE;
X    rplc_mode = TRUE;
X    cur_prompt = MSG_sch_str;
X    if (s = readpattern ())
X        {
X        replaceit ();
X        }
X    srch_mode = FALSE;
X    rplc_mode = FALSE;
X    return (s);
X}
X
X
Xchar    replaceit ()
X{
X    register int    s;
X    int     rcnt = 0;           /* Replacements made so far */
X    int     plen;               /* length of found string   */
X    int     rlen;               /* length of replace string   */
X    long    abs_dot_p;          /* absolute dot position */
X    long    abs_mark_p;         /* absolute mark position */
X    char    buf[80], buf1[80];
X
X /* 
X  * Search forward repeatedly, checking each time whether to insert
X  * or not.  The "!" case makes the check always true, so it gets put
X  * into a tighter loop for efficiency.
X  *
X  * If we change the line that is the remembered value of dot, then
X  * it is possible for the remembered value to move.  This causes great
X  * pain when trying to return to the non-existant line.
X  *
X  * possible fixes:
X  * 1) put a single, relocated marker in the WINDOW structure, handled
X  *    like mark.  The problem now becomes a what if two are needed...
X  * 2) link markers into a list that gets updated (auto structures for
X  *    the nodes)
X  * 3) Expand the mark into a stack of marks and add pushmark, popmark.
X  */
X
X    plen = srch_pat -> l_used;
X    rlen = rplc_pat -> l_used;
X
X    abs_dot_p = DOT_POS(curwp); /* save current dot position */
X    abs_mark_p = MARK_POS(curwp);
X
X    while (forwsrch () == TRUE)
X        {
Xretry: 
X        sprintf (buf1, MSG_fnd_at, R_POS_FMT(curwp));
X        sprintf (buf, buf1, DOT_POS(curwp));
X        writ_echo (buf);
X        curwp -> w_flag |= WFMODE;  /* update mode line */
X        update ();
X        switch (ttgetc ())
X            {
X            case 'r':
X            case 'R':
X            case ' ': 
X            case ',': 
X                /* update has fixedup the dot position so move to found byte */
X                /* go and do the replace */
X                if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
X                    return (FALSE);
X                /* begin searching after replace string */
X                move_ptr (curwp, (long)rlen, TRUE, FALSE, TRUE);
X                rcnt++;
X                break;
X
X            case 'o':
X            case 'O':
X            case '.': 
X                if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
X                    return (FALSE);
X                /* begin searching after replace string */
X                move_ptr (curwp, (long)rlen, TRUE, FALSE, TRUE);
X                rcnt++;
X                goto stopsearch;
X
X            case 'q':
X            case 'Q':
X            case CCHR ('G'): 
X                ctrlg (FALSE, 0, KRANDOM);
X                goto stopsearch;
X
X            case 'a':
X            case 'A':
X            case '!': 
X                do
X                    {
X                    if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
X                        return (FALSE);
X                    /* begin searching after replace string */
X                    move_ptr (curwp, (long)rlen, TRUE, FALSE, TRUE);
X                    rcnt++;
X                    }
X                while (forwsrch () == TRUE);
X                goto stopsearch;
X
X            case 's':
X            case 'S':
X            case 'n': 
X                /* begin searching after this byte */
X                move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
X                break;
X
X            default:
X                ttbeep ();
X                goto retry;
X            }
X        }
X
Xstopsearch: 
X    move_ptr (curwp, abs_dot_p, TRUE, TRUE, FALSE);
X    if (curwp -> w_markp != NULL)
X        {
X        swapmark ();
X        /* insure that the mark points to the same byte as before */
X        if (abs_mark_p > abs_dot_p)
X            move_ptr (curwp, abs_mark_p + rlen - plen, TRUE, FALSE, FALSE);
X        else
X            move_ptr (curwp, abs_mark_p, TRUE, FALSE, FALSE);
X        swapmark ();
X        }
X    curwp -> w_flag |= WFHARD;
X    update ();
X    if (rcnt == 0)
X        {
X        writ_echo (MSG_no_rpl);
X        }
X    else if (rcnt == 1)
X        {
X        writ_echo (MSG_1_rpl);
X        }
X    else
X        {
X        sprintf (buf1, MSG_n_rpl, R_POS_FMT(curwp));
X        sprintf (buf, buf1, (ulong)rcnt);
X        writ_echo (buf);
X        }
X    flush_count += rcnt;        /* jam for auto write buffers */
X    return (TRUE);
X}
X
X
X/*
X* This routine does the real work of a
X* forward search. The pattern is sitting in the external
X* variable "srch_pat" the mask if in "srch_mask".
X* If found, dot is updated, the window system
X* is notified of the change, and TRUE is returned. If the
X* string isn't found, FALSE is returned.
X*/
Xchar    forwsrch ()
X{
X    register    LINE    *save_dotp, *save2_dotp;
X    register    int     save_doto, save2_doto;
X    register    char    *pat_ptr, *mask_ptr;
X    register    int     i, j, pat_cnt;
X    register    char    first_pat, first_mask;
X    char        buf[80], buf1[40];
X
X    save_dotp = curwp -> w_dotp;    /* save dot position for later */
X    save_doto = curwp -> w_doto;
X    pat_ptr = srch_pat -> l_text;
X    mask_ptr = srch_mask -> l_text;
X    pat_cnt = srch_pat -> l_used;
X    first_mask = mask_ptr[0];
X    first_pat = pat_ptr[0] | first_mask;
X    j =  (int)DOT_POS(curwp) & 0xffff;
X
X    do 
X    {
X        if ((j++ & 0x2ff) == 0)
X        {
X            sprintf (buf1, MSG_srcing, R_POS_FMT(curwp));
X            sprintf (buf, buf1, DOT_POS(curwp));
X            writ_echo (buf);
X            /* check if we should quit */
X            if (ttkeyready ())
X            {
X                ttgetc ();  /* through away char that was struck */
X                break;
X            }
X        }   
X        if (first_pat == 
X            ((DOT_CHAR(curwp) | first_mask) & 0xff))
X        {
X            save2_dotp = curwp -> w_dotp;    /* save dot position for later */
X            save2_doto = curwp -> w_doto;
X            for (i = 1; i < pat_cnt; i++)
X            {
X                if (!move_ptr (curwp, 1L, TRUE, FALSE, TRUE) ||
X                    ((pat_ptr[i] & ~mask_ptr[i]) != 
X                    (DOT_CHAR(curwp) & ~mask_ptr[i])))
X                {   /* not found */
X                    curwp -> w_dotp = save2_dotp;  /* restore dot position */
X                    curwp -> w_doto = save2_doto;
X                    break;
X                }
X            }
X            if (i == pat_cnt)   /* found */
X            {   /* move back to the first matching unit */
X                move_ptr (curwp, -(long)pat_cnt + 1, TRUE, FALSE, TRUE);
X                wind_on_dot (curwp);
X                return (TRUE);
X            }
X        }
X    }
X    while (move_ptr (curwp, 1L, TRUE, FALSE, TRUE));
X
X    curwp -> w_dotp = save_dotp;  /* restore dot position */
X    curwp -> w_doto = save_doto;
X    return (FALSE);
X}
X
X
X/*
X* This routine does the real work of a
X* backward search. The pattern is sitting in the external
X* variable "srch_pat". If found, dot is updated, the window system
X* is notified of the change, and TRUE is returned. If the
X* string isn't found, FALSE is returned.
X*/
Xchar    backsrch ()
X{
X    register    LINE    *save_dotp, *save_p;
X    register    int     save_doto, save_o;
X    register    char    *pat_ptr, *mask_ptr;
X    register    int     i, j, pat_cnt;
X    register    char    first_pat, first_mask;
X    char        buf[80], buf1[40];
X
X    save_dotp = curwp -> w_dotp;    /* save dot position for later */
X    save_doto = curwp -> w_doto;
X    pat_ptr = srch_pat -> l_text;
X    mask_ptr = srch_mask -> l_text;
X    pat_cnt = srch_pat -> l_used;
X    first_mask = mask_ptr[0];
X    first_pat = pat_ptr[0] | first_mask;
X    j =  (int)DOT_POS(curwp) & 0xffff;
X
X    do 
X    {
X        /* check if we should quit */
X        if (ttkeyready ())
X        {
X            ttgetc ();  /* through away char that was struck */
X            break;
X        }
X        if ((j-- & 0x2ff) == 0)
X        {
X            sprintf (buf1, MSG_srcing, R_POS_FMT(curwp));
X            sprintf (buf, buf1, DOT_POS(curwp));
X            writ_echo (buf);
X        }   
X        if (first_pat == 
X            (curwp -> w_dotp -> l_text[curwp -> w_doto] | first_mask))
X        {
X
X            save_p = curwp -> w_dotp; 
X            save_o = curwp -> w_doto;
X            for (i = 1; i < pat_cnt; i++)
X            {
X                if (!move_ptr (curwp, 1L, TRUE, FALSE, TRUE) ||
X                   ((pat_ptr[i] & ~mask_ptr[i]) != 
X                   (DOT_CHAR(curwp) & ~mask_ptr[i])))
X                {   /* not found */
X                    curwp -> w_dotp = save_p;   /* restore ptr to continue */ 
X                    curwp -> w_doto = save_o;
X                    break;
X                }
X            }
X            if (i == pat_cnt)   /* found */
X            {   /* move back to the first matching unit */
X                move_ptr (curwp, -(long)pat_cnt + 1, TRUE, FALSE, TRUE);
X                wind_on_dot (curwp);
X                return (TRUE);
X            }
X        }
X    }
X    while (move_ptr (curwp, -1L, TRUE, FALSE, TRUE));
X
X    curwp -> w_dotp = save_dotp;  /* restore dot position */
X    curwp -> w_doto = save_doto;
X    return (FALSE);
X}
X
X/*
X* Read a pattern.
X* Display and edit in the form of the current window.
X* Slide the displayed line back and forth when the cursor hits a boundary.
X* Manage the mask buffer. When a '*' (wild card) is entered mask all
X* bits in that unit and display all '?'s.
X*/
Xchar    readpattern ()
X{
X    int     cod, mask_cod, curs_pos, curs_pos1, prt_siz, i, doto, loff;
X    WINDOW  srch_wind, *save_wind;
X    BUFFER  srch_buf, *save_buf;
X    LINE    head_line, *line_ptr1, *line_ptr2;
X    char    disp_buf[120],
X            mask_buf[120],
X            buf1[80],
X            siz_prompt2,
X            r_type,
X            first_time,
X            u_off,
X            stat;
X
X
X    save_wind = curwp;          /* save current window for later */
X    save_buf = curbp;       /* save current buffer for later */
X
X    curwp = &srch_wind;         /* search window is current window during
X                                   search */
X    curbp = &srch_buf;
X    cur_pat = srch_pat;         /* set global variables for LINE finctions */
X    cur_mask = srch_mask;
X
X    recall_flag = FALSE;
X    first_time = TRUE;
X    read_pat_mode = TRUE;
X    curwp -> w_wndp = NULL;
X    curwp -> w_bufp = curbp;
X    curwp -> w_linep = cur_pat;
X    curwp -> w_loff = 0;
X    curwp -> w_dotp = cur_pat;
X    curwp -> w_doto = 0;
X    curwp -> w_unit_offset = 0;
X    curwp -> w_toprow = 24;
X    curwp -> w_ntrows = 1;
X    curwp -> w_intel_mode = save_wind -> w_intel_mode;
X    curwp -> w_disp_shift = 0;
X    if (R_TYPE(save_wind) == TEXT)
X        curwp -> w_fmt_ptr = &ascii_s_fmt;
X    else
X        curwp -> w_fmt_ptr = save_wind -> w_fmt_ptr -> r_srch_fmt;
X
X    srch_buf.b_bufp = NULL;
X    srch_buf.b_linep = &head_line;
X    srch_buf.b_unit_offset = 0;    /* unit offset   pvr */
X    srch_buf.b_markp = NULL;
X    srch_buf.b_marko = 0;
X    srch_buf.b_flag = 0;
X    srch_buf.b_nwnd = 1;
X    srch_buf.b_fname[0] = 0;
X    srch_buf.b_bname[0] = 0;
X
X    head_line.l_fp = cur_pat;
X    head_line.l_bp = cur_pat;
X    head_line.l_file_offset = 0;    /* pvr */
X    head_line.l_used = 0;
X    head_line.l_size = 0;
X        
X    cur_pat -> l_fp = &head_line;
X    cur_pat -> l_bp = &head_line;
X    cur_pat -> l_size = 266;    /* leave some extra past 256 */
X    cur_pat -> l_used = 0;
X    cur_pat -> l_file_offset = 0;
X
X    cur_mask -> l_fp = &head_line;
X    cur_mask -> l_bp = &head_line;
X    cur_mask -> l_size = 266;   /* leave some extra past 256 */
X    cur_mask -> l_used = 0;
X    cur_mask -> l_file_offset = 0;
X
X    rplc_pat -> l_fp = &head_line;
X    rplc_pat -> l_bp = &head_line;
X    rplc_pat -> l_size = 266;    /* leave some extra past 256 */
X    rplc_pat -> l_used = 0;
X    rplc_pat -> l_file_offset = 0;
X
X    rplc_mask -> l_fp = &head_line;
X    rplc_mask -> l_bp = &head_line;
X    rplc_mask -> l_size = 266;   /* leave some extra past 256 */
X    rplc_mask -> l_used = 0;
X    rplc_mask -> l_file_offset = 0;
X 
X    sprintf (buf1, MSG_curs, cur_prompt, R_BYTE_FMT(curwp),
X                 R_BYTE_FMT(curwp), R_BYTE_FMT(curwp));
X    sprintf (disp_buf, buf1, curwp -> w_doto,
X        curwp -> w_fmt_ptr -> r_chr_per_u - curwp -> w_unit_offset - 1,
X        curwp -> w_dotp -> l_used);
X
X    siz_prompt2 = strlen (disp_buf); /* save prompt length for later */
X
X    for (i = siz_prompt2; i < NCOL; i++)    /* clear rest of buffer */
X        disp_buf [i] = ' ';
X
X    writ_echo (disp_buf);
X
X    r_type = R_TYPE(curwp);
X
X    while (TRUE)
X        {
X        /* position cursor */
X        curs_pos = curwp -> w_doto - curwp -> w_loff;
X        if (curwp -> w_fmt_ptr -> r_size == 1)
X            {
X            curs_pos >>= 1;
X            }
X        else if (curwp -> w_fmt_ptr -> r_size == 3)
X            {
X            curs_pos >>= 2;
X            }
X        curs_pos1 = curwp -> w_fmt_ptr -> r_positions[curs_pos] + 
X                    curwp -> w_unit_offset + siz_prompt2;
X        ttmove (nrow - 1, curs_pos1);
X		ttflush ();
X		
X        cod = getkey ();
X
X        if (cod == 0x014D)  /* check for return */
X            {
X            if ((rplc_mode == TRUE) && (cur_prompt == MSG_sch_str))
X                {
X                next_pat ();
X                dont_repeat = FALSE;    /* fix up */
X                goto next_loop;
X                }
X            else
X                {
X                old_srch_pat_size = srch_pat -> l_used; /* save for restore */
X                if (rplc_mode == TRUE)
X                   old_rplc_pat_size = rplc_pat -> l_used;
X
X                old_fmt = curwp -> w_fmt_ptr;
X                curwp = save_wind;  /* restore current window */
X                curbp = save_buf;  /* restore current buffer */
X                read_pat_mode = FALSE;
X                return (TRUE);
X                }
X            }
X
X        if ((cod >= ' ') && (cod < 0x7f)) 
X            {
X            if ((r_type == ASCII) || (r_type == EBCDIC))
X                {
X                mask_cod = '9'; /* use 9 as dummy char that will get through */
X                }
X            else if (r_type == DECIMAL)
X                {
X                mask_cod = '0'; /* clear mask byte */
X                }
X            else if (cod == '?')
X                {
X                cod = '0';
X                switch (r_type)
X                    {
X                    case OCTAL:
X                        if (curwp -> w_unit_offset == 0)    /* if first char */
X                            {
X                            if (R_SIZE(curwp) == WORDS)
X                                mask_cod = '1';
X                            else
X                                mask_cod = '3';
X                            }
X                        else
X                            mask_cod = '7';
X                        break;
X    
X                    case HEX:
X                        mask_cod = 'F';
X                        break;
X    
X                    case BINARY:
X                        mask_cod = '1';
X                        break;
X#if RUNCHK
X                    default:
X                        printf (ERR_rdpat);
X                        break;
X#endif
X                    }
X                }
X            else
X                {
X                mask_cod = '0';
X                }        
X            }
X        else
X            mask_cod = cod;     /* must be control; do the same to the mask */
X
X        /* save current dot and window positions */
X        doto = curwp -> w_doto;
X        u_off = curwp -> w_unit_offset;
X        loff = curwp -> w_loff;
X        stat = execute (cod, FALSE, 1);
X
X        if (stat == ABORT)
X            {
X            old_srch_pat_size = srch_pat -> l_used; /* save for restore */
X            if (rplc_mode == TRUE)
X               old_rplc_pat_size = rplc_pat -> l_used;
X            old_fmt = curwp -> w_fmt_ptr;
X            curwp = save_wind;  /* restore current window */
X            curbp = save_buf;  /* restore current buffer */
X            read_pat_mode = FALSE;
X            return (FALSE);
X            }
X
X       /* If key is recall then reset the size variables */
X        if (first_time)
X            {
X            first_time = FALSE;
X            if (recall_flag)
X                {
X                srch_pat -> l_used = old_srch_pat_size;
X                srch_mask -> l_used = old_srch_pat_size;
X                rplc_pat -> l_used = old_rplc_pat_size;
X                rplc_mask -> l_used = old_rplc_pat_size;
X                curwp -> w_fmt_ptr = old_fmt;
X                recall_flag = FALSE;
X                }
X            }
X
X        /* if it was a toggling command, don't do it again */
X        if (!dont_repeat &&
X            (stat == TRUE))
X        {
X            head_line.l_fp = cur_mask;   /* point to mask */
X            head_line.l_bp = cur_mask;
X            curwp -> w_linep = cur_mask;
X            curwp -> w_dotp = cur_mask;
X            curwp -> w_loff = loff;
X            curwp -> w_doto = doto;
X            curwp -> w_unit_offset = u_off;
X            execute (mask_cod, FALSE, 1);
X    
X            head_line.l_fp = cur_pat;    /* restore pointers */
X            head_line.l_bp = cur_pat;
X            curwp -> w_linep = cur_pat;
X            curwp -> w_dotp = cur_pat;
X        }
X        else
X            dont_repeat = FALSE;
X
X        /* limit at 256 bytes */
X        if (cur_pat -> l_used >= 256)
X            {
X            cur_mask -> l_used = 255; 
X            cur_pat -> l_used = 255;
X            if (curwp -> w_doto >= 256)
X                {
X                move_ptr (curwp, 255L, TRUE, TRUE, FALSE);  /* last position */
X                }
X            }
X
X        /* if buffer is size locked then replace pattern must be the */
X        /* same size as the search pattern */
X        if (rplc_mode && (save_buf -> b_flag & BFSLOCK))
X            {
X            rplc_pat -> l_used = srch_pat -> l_used; 
X            rplc_mask -> l_used = srch_pat -> l_used; 
X            }
X
X        r_type = R_TYPE(curwp);
X#if RUNCHK
X        /* check that the pattern and the mask are the same size */
X        if (cur_pat -> l_used != cur_mask -> l_used)
X            {
X            printf (ERR_mask, cur_pat -> l_used, cur_mask -> l_used); 
X            }   
X
X        /* check that in ascii mode the byte that will be set to zero */
X        /* is the dummy char 9 */
X/*        if (((r_type == ASCII) &&
X            (cur_mask -> l_text[curwp -> w_doto - 1] != '9'))
X            ||
X            ((r_type == EBCDIC) &&
X            (cur_mask -> l_text[curwp -> w_doto - 1] != to_ebcdic('9'))))
X            printf (ERR_m_cl);
X*/
X#endif
X        if (((r_type == ASCII) ||
X            (r_type == EBCDIC)) &&
X           ((cod >= ' ') && (cod < 0x7f))) 
X            cur_mask -> l_text[doto] = 0; /* clear mask byte */
X
Xnext_loop:
X        sprintf (buf1, MSG_curs, cur_prompt, R_BYTE_FMT(curwp),
X                     R_BYTE_FMT(curwp), R_BYTE_FMT(curwp));
X        sprintf (disp_buf, buf1, curwp -> w_doto,
X            curwp -> w_fmt_ptr -> r_chr_per_u - curwp -> w_unit_offset - 1,
X            curwp -> w_dotp -> l_used);
X
X        siz_prompt2 = strlen (disp_buf); /* save prompt length for later */
X
X        for (i = siz_prompt2; i < NCOL; i++)
X            {
X            disp_buf [i] = ' ';
X            mask_buf [i] = ' ';
X            }
X
X        if ((curbp -> b_flag & BFSLOCK) &&
X            (rplc_pat -> l_used != srch_pat -> l_used))
X            {
X            rplc_pat -> l_used = srch_pat -> l_used;
X            /* if dot is past the end then move it back, replace string only */
X            if (DOT_POS(curwp) > srch_pat -> l_used)
X                move_ptr (curwp, (long)srch_pat -> l_used, TRUE, TRUE, FALSE);
X            }
X
X        wind_on_dot (curwp);
X
X        /* figure number of bytes to convert to text */
X        if ((cur_pat -> l_used - curwp -> w_loff) <
X                 (prt_siz = curwp -> w_fmt_ptr -> r_bytes))
X            prt_siz = cur_pat -> l_used - curwp -> w_loff;
X
X        bin_to_text (&cur_pat -> l_text[curwp -> w_loff],
X                &disp_buf[siz_prompt2],
X                prt_siz, curwp -> w_fmt_ptr);
X
X        /* change any char to a ? if any bit is set in the mask buffer */
X        if ((r_type != ASCII) && (r_type != EBCDIC))
X            {
X            /* print the contents of the mask to a invisible buffer */
X            bin_to_text (&cur_mask -> l_text[curwp -> w_loff],
X                    &mask_buf[siz_prompt2],
X                    prt_siz, curwp -> w_fmt_ptr);
X
X            for (i = siz_prompt2; (disp_buf[i] != 0) && (i < NCOL); i++)
X                {
X                if ((mask_buf[i] != '0') &&
X                    (mask_buf[i] != ' '))
X                    disp_buf[i] = '?';  
X                }
X            }
X        else
X            {
X            for (i = 0; i < prt_siz; i++)
X                {
X                if (cur_mask -> l_text[curwp -> w_loff + i] != 0)
X                    disp_buf[i + siz_prompt2] = '?';  
X                }
X            }
X        writ_echo (disp_buf);
X    }
X}
X
X/*
X*   Recall the last contents of the search string
X*/
Xbool    recall ()
X    {
X    recall_flag = TRUE;
X    return (TRUE);
X    }
X
X/*
X*   Switch between search pattern and replace pattern and their 
X*   respective masks 
X*/
Xvoid    next_pat ()
X{
X    if (cur_pat == srch_pat)
X    {
X        cur_prompt = MSG_rpl_str;
X        cur_pat = rplc_pat; /* point to replace pattern */
X        cur_mask = rplc_mask;
X    }
X    else
X    {
X        cur_prompt = MSG_sch_str;
X        cur_pat = srch_pat;     /* point to search pattern */
X        cur_mask = srch_mask;
X    }
X    curwp -> w_dotp = cur_pat;
X    curwp -> w_linep = cur_pat;
X    curbp -> b_linep -> l_fp = cur_pat;
X    curbp -> b_linep -> l_bp = cur_pat;
X
X    if (curwp -> w_doto > cur_pat -> l_used)
X        {
X        curwp -> w_doto = cur_pat -> l_used;
X        curwp -> w_unit_offset = 0;
X        }
X    if (curwp -> w_loff > cur_pat -> l_used)
X        curwp -> w_loff = cur_pat -> l_used;
X    dont_repeat = TRUE;
X}
X
X/*
X* Compare the contents of two windows.
X* There must be exactly two windows displayed.
X* The bytes under the cursor in each window are compared and if 
X* a difference is found then the loop is stopped with the dot
X* position in each window pointing to the difference.
X* The two windows can be pointing at the same or different buffers.
X*/
Xbool    compare ()
X
X    {
X    WINDOW  *wp1, *wp2;
X    bool    move1, move2;
X    int     j;  
X    char    *term_str = MSG_cmp_dif;
X    char    buf[80], buf1[60];
X
X    if (wheadp -> w_wndp -> w_wndp != NULL)
X        {
X        writ_echo (MSG_only_2);
X        return (FALSE);
X        }
X        
X    wp1 = wheadp;
X    wp2 = wheadp -> w_wndp;
X    j =  (int)DOT_POS(curwp) & 0xffff;
X
X    wp1 -> w_flag |= WFMOVE;
X    wp2 -> w_flag |= WFMOVE;
X
X    while (DOT_CHAR(wp1) == DOT_CHAR(wp2))
X        {
X        if ((j++ & 0xff) == 0)
X            {
X            sprintf (buf1, MSG_cmping, R_POS_FMT(curwp));
X            sprintf (buf, buf1, DOT_POS(curwp));
X            writ_echo (buf);
X           /* check if we should quit */
X           if (ttkeyready ())
X                {
X                ttgetc ();  /* through away char that was struck */
X                term_str = MSG_cmp_term;
X                break;
X                }
X            }   
X        move1 = move_ptr (wp1, 1L, TRUE, FALSE, TRUE);  
X        move2 = move_ptr (wp2, 1L, TRUE, FALSE, TRUE);  
X
X        if (!(move1 && move2))
X            {
X            term_str = MSG_cmp_end;
X            break;
X            }
X        }
X        writ_echo (term_str);
X        wind_on_dot (wp1);
X        wind_on_dot (wp2);
X        return (TRUE);
X    }
END_OF_FILE
if test 30053 -ne `wc -c <'search.c'`; then
    echo shar: \"'search.c'\" unpacked with wrong size!
fi
chmod +x 'search.c'
# end of 'search.c'
fi
echo shar: End of archive 6 \(of 10\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

-- 
>>>>>>>>>>>>>>>> Peter Reilley ..... pvr@wang.com <<<<<<<<<<<<<<<<<<<<<<<
                     Well, that about says it.

pvr@wang.com (Peter Reilley) (06/06/91)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 7 (of 10)."
# Contents:  random.c
# Wrapped by pvr@elf on Thu Mar 14 08:16:47 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'random.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'random.c'\"
else
echo shar: Extracting \"'random.c'\" \(30423 characters\)
sed "s/^X//" >'random.c' <<'END_OF_FILE'
X/*
X*              Assorted commands.
X* The file contains the command
X* processors for a large assortment of unrelated
X* commands. The only thing they have in common is
X* that they are all command processors.
X*/
X
X#include    "def.h"
X
Xchar    backdel ();
Xbool    fill_out ();
Xvoid    bad_key ();
X
X
X
Xextern    char    MSG_sh_pos[];
Xextern    char    MSG_sh_pos1[];
Xextern    char    MSG_f_str[];
Xextern    char    MSG_3u[];
Xextern    char    MSG_5u[];
Xextern    char    MSG_lu[];
Xextern    char    MSG_03u[];
Xextern    char    MSG_05u[];
Xextern    char    MSG_010lu[];
Xextern    char    MSG_lnk[];
Xextern    char    MSG_unlink[];
Xextern    char    MSG_link[];
Xextern    char    MSG_bad_key[];
Xextern    char    MSG_esc[];
Xextern    char    MSG_ctl_x[];
Xextern    char    MSG_ctl[];
Xextern    char    MSG_key_code[];
Xextern    char    char_str[];
X
X#if RUNCHK
Xextern    char    ERR_rnd_1[];
Xextern    char    ERR_rnd_2[];
Xextern    char    ERR_rnd_3[];
Xextern    char    ERR_rnd_4[];
Xextern    char    MSG_rnd_5[];
Xextern    char    ERR_rnd_6[];
Xextern    char    ERR_rnd_7[];
X#endif
X#include    "lintfunc.dec"
X
Xextern  ROW_FMT ascii_fmt;
Xextern  ROW_FMT ebcdic_fmt;
Xextern  ROW_FMT binary_8_fmt;
Xextern  ROW_FMT binary_16_fmt;
Xextern  ROW_FMT binary_32_fmt;
Xextern  ROW_FMT octal_8_fmt;
Xextern  ROW_FMT octal_16_fmt;
Xextern  ROW_FMT octal_32_fmt;
Xextern  ROW_FMT decimal_8_fmt;
Xextern  ROW_FMT decimal_16_fmt;
Xextern  ROW_FMT decimal_32_fmt;
Xextern  ROW_FMT hex_8_fmt;
Xextern  ROW_FMT hex_16_fmt;
Xextern  ROW_FMT hex_32_fmt;
X
Xextern  bool    read_pat_mode;
Xextern  bool    dont_repeat;
X
Xchar    dec_chr_ok ();
Xulong   get_long ();
X
X/*
X* Display a bunch of useful information about
X* the current location of dot and mark.
X* The position of the dot and mark and the difference between them.
X* The total buffer size is displayed.
X* This is normally bound to "C-X =".
X*/
Xbool showcpos (f, n, k)
X{
X
X    A32     dotoff,
X            markoff,
X            fsize,
X            bsize;
X    char    buf[80], buf1[80];
X
X    dotoff = curwp -> w_dotp -> l_file_offset;
X    dotoff += curwp -> w_doto;
X
X    if (curwp -> w_markp != NULL)
X        {
X        markoff = curwp -> w_markp -> l_file_offset;
X        markoff += curwp -> w_marko;
X        }
X
X    bsize = curwp -> w_bufp -> b_linep -> l_bp -> l_file_offset;
X    bsize += curwp -> w_bufp -> b_linep -> l_bp -> l_used;
X    fsize = curbp -> b_file_size;
X
X    if (curwp -> w_markp != NULL)
X        {
X        /* build format string */
X        sprintf (buf1, MSG_sh_pos, R_POS_FMT(curwp), R_POS_FMT(curwp), 
X                                R_POS_FMT(curwp), R_POS_FMT(curwp)); 
X        sprintf (buf, buf1, dotoff, markoff, bsize, fsize);
X        }
X    else
X        {
X        /* build format string */
X        sprintf (buf1, MSG_sh_pos1, R_POS_FMT(curwp), R_POS_FMT(curwp), 
X                                R_POS_FMT(curwp)); 
X        sprintf (buf, buf1, dotoff, bsize, fsize);
X        }
X
X    sprintf (&buf[strlen(buf)], MSG_f_str, curbp -> b_fname);
X    writ_echo (buf);
X
X    return (TRUE);
X}
X
X
X/*
X* Twiddle the two characters on either side of
X* dot. If dot is at the end of the line twiddle the
X* two characters before it. Return with an error if dot
X* is at the beginning of line; it seems to be a bit
X* pointless to make this work. This fixes up a very
X* common typo with a single stroke. Normally bound
X* to "C-T". This always works within a line, so
X* "WFEDIT" is good enough.
X*/
Xbool twiddle ()
X{
X
X    register    LINE * dotp;
X    register short  doto;
X    register int    cl;
X    register int    cr;
X    char    b_per_u,
X            f_buf[4],
X            s_buf[4],
X            i;
X
X    dotp = curwp -> w_dotp;
X    doto = curwp -> w_doto;
X    b_per_u = curwp -> w_fmt_ptr -> r_b_per_u;
X /* try to move back one unit */
X    if (!move_ptr (curwp, (long) - b_per_u, TRUE, TRUE, TRUE))
X        {
X        curwp -> w_dotp = dotp; /* if fail then restore dot and quit */
X        curwp -> w_doto = doto;
X        ttbeep ();
X        return (FALSE);
X        }
X /* pick up first unit byte by byte */
X    for (i = 0; i < b_per_u; i++)
X        {
X        f_buf[i] = DOT_CHAR(curwp);
X        move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
X        }
X /* move to the end of the second unit */
X    if (!move_ptr (curwp, (long) (b_per_u - 1), TRUE, FALSE, TRUE))
X        {
X        curwp -> w_dotp = dotp; /* if fail then restore dot and quit */
X        curwp -> w_doto = doto;
X        ttbeep ();
X        return (FALSE);
X        }
X /* pick up second unit (reverse order) and deposit second unit */
X    for (i = 0; i < b_per_u; i++)
X        {
X        s_buf[i] = DOT_CHAR(curwp);
X        DOT_CHAR(curwp) = f_buf[b_per_u - 1 - i];
X        move_ptr (curwp, -1L, TRUE, FALSE, TRUE);
X        }
X /* deposit first unit */
X    for (i = 0; i < b_per_u; i++)
X        {
X        DOT_CHAR(curwp) = s_buf[i];
X        move_ptr (curwp, -1L, TRUE, FALSE, TRUE);
X        }
X    curwp -> w_dotp = dotp;
X    curwp -> w_doto = doto;
X    lchange (WFHARD);
X    return (TRUE);
X}
X
X/*
X* Quote the next character, and
X* insert it into the buffer. All the characters
X* are taken literally.
X* The character
X* is always read, even if it is inserted 0 times, for
X* regularity.
X*/
Xbool quote (f, n, k)
X{
X
X    register int    s;
X    register int    c;
X
X    if (kbdmop != NULL)
X        c = *kbdmop++;
X    else
X        {
X        c = ttgetc ();
X        if (kbdmip != NULL)
X            {
X            if (kbdmip > &kbdm[NKBDM - 4])
X                {
X                ctrlg (FALSE, 0, KRANDOM);
X                return (ABORT);
X                }
X
X            *kbdmip++ = c;
X            }
X
X        }
X
X    if (n < 0)
X        return (FALSE);
X    if (n == 0)
X        return (TRUE);
X
X    return (linsert (n, c));
X}
X
X/*
X* Toggle the insert mode.  Insert mode is used only in ASCII or EBCDIC modes.
X*/
Xbool insert_toggle ()    /* toggle routine for selfinsert */
X{
X    register    WINDOW * wp;
X
X    if (curbp -> b_flag & BFSLOCK)
X        return (TRUE);
X    
X    if (read_pat_mode)
X        dont_repeat = TRUE;
X
X    insert_mode = !insert_mode;
X    for (wp = wheadp; wp; wp = wp -> w_wndp)
X        wp -> w_flag |= WFMODE; /* force mode line update */
X    return (TRUE);
X}
X
X/*
X* Ordinary text characters are bound to this function,
X* which inserts them into the buffer. Characters marked as control
X* characters (using the CTRL flag) may be remapped to their ASCII
X* equivalent. This makes TAB (C-I) work right, and also makes the
X* world look reasonable if a control character is bound to this
X* this routine by hand. Any META or CTLX flags on the character
X* are discarded. 
X* 
X*   Edit the unit under the cursor.
X*   Check that the character is valid for the current display mode.
X*/
X
Xbool selfinsert (f, n, k)
X{
X
X    register int    c;
X    register int    s;
X    char    edt_buf[4],
X            i_chr,
X            b_per_u,
X            u_offs,
X            u_roffs,
X            bit_shf,
X            bit_mask,
X            i;
X    LINE    * l_ptr;
X    short   d_offs;
X    int     bytes,
X            temp_int;
X    long    dot_shf,
X            l_mask,
X            l_val;
X    char    text_buf[12];
X    static char max_dec_8[] = "255";
X    static char max_dec_16[] = "65535";
X    static char max_dec_32[] = "4294967295";
X	int		cur_col;
X
X    bool intel;
X
X    if (n < 0)
X        {
X        ttbeep ();
X        return (FALSE);
X        }
X    if (n == 0)
X        {
X        ttbeep ();
X        return (TRUE);
X        }
X    c = k & KCHAR;
X    if ((k & KCTRL) != 0 && c >= '@' && c <= '_')/* ASCII-ify.           */
X        c -= '@';
X    b_per_u = curwp -> w_fmt_ptr -> r_b_per_u;
X    u_offs = curwp -> w_unit_offset;
X    u_roffs = curwp -> w_fmt_ptr -> r_chr_per_u - u_offs - 1;
X    intel = curwp -> w_intel_mode;
X
X	cur_col = ttcol;
X
X    switch (curwp -> w_fmt_ptr -> r_type)
X        {
X        case EBCDIC: 
X            c = to_ebcdic (c);  /* convert ASCII to EBCDIC */
X        case ASCII: 
X            if ((insert_mode) || (DOT_POS(curwp) == BUF_SIZE(curwp)))
X                {
X                s = linsert (n, c);
X                if (read_pat_mode)
X                    forwchar (0, 1, KRANDOM);/* advance the cursor */
X                }
X            else
X                s = lreplace (n, c);
X            break;
X
X        case HEX: 
X            if ((c >= '0') && (c <= '9'))
X                {
X                i_chr = c - '0';/* convert to binary */
X                }
X            else
X                if ((c >= 'A') && (c <= 'F'))
X                    {
X                    i_chr = c - 'A' + 10;/* convert to binary */
X                    }
X                else
X                    if ((c >= 'a') && (c <= 'f'))
X                        {
X                        i_chr = c - 'a' + 10;/* convert to binary */
X                        }
X                    else
X                        {
X                        bad_key (k);
X                        return (FALSE);
X                        }
X            fill_out (); /* expand buffer if necessary */
X
X        /* position dot to byte to be altered */
X            if (intel)
X                dot_shf = u_roffs >> 1;
X            else
X                dot_shf = u_offs >> 1;
X
X            /* save dot position for later */
X            l_ptr = curwp -> w_dotp;
X            d_offs = curwp -> w_doto;
X            move_ptr (curwp, dot_shf, TRUE, FALSE, TRUE);
X
X            if (u_offs & 1)
X                {               /* lower nibble in byte */
X                i_chr &= 0x0f;
X                DOT_CHAR(curwp) &= 0xf0;
X                DOT_CHAR(curwp) |= i_chr;
X                }
X            else
X                {               /* upper nibble in byte */
X                i_chr <<= 4;
X                i_chr &= 0xf0;
X                DOT_CHAR(curwp) &= 0x0f;
X                DOT_CHAR(curwp) |= i_chr;
X                }
X
X        /* restore dot position */
X            curwp -> w_dotp = l_ptr;
X            curwp -> w_doto = d_offs;
X            forwchar (0, 1, KRANDOM);/* advance the cursor */
X            break;
X
X        case BINARY: 
X            if ((c != '0') && (c != '1'))
X                {
X                bad_key (k);
X                return (FALSE);
X                }
X
X        /* position dot to byte to be altered */
X            if (intel)
X                dot_shf = u_roffs >> 3;
X            else
X                dot_shf = u_offs >> 3;
X
X            fill_out (); /* expand buffer if necessary */
X
X            /* save dot position for later */
X            l_ptr = curwp -> w_dotp;
X            d_offs = curwp -> w_doto;
X            move_ptr (curwp, dot_shf, TRUE, FALSE, TRUE);
X
X            bit_shf = u_roffs & 0x07;
X
X            if (c == '0')
X                {
X                DOT_CHAR(curwp) &= ~(1 << bit_shf);
X                }
X            else
X                {
X                DOT_CHAR(curwp) |= 1 << bit_shf;
X                }
X
X        /* restore dot position */
X            curwp -> w_dotp = l_ptr;
X            curwp -> w_doto = d_offs;
X            forwchar (0, 1, KRANDOM);/* advance the cursor */
X            break;
X
X        case OCTAL: 
X            if (c < '0')
X                {
X                bad_key (k);
X                return (FALSE);
X                }
X            else
X                if ((c > '1') && (u_offs == 0) &&
X                        ((curwp -> w_fmt_ptr -> r_size) == WORDS))
X                    {
X                    bad_key (k);
X                    return (FALSE);
X                    }
X                else
X                    if ((c > '3') && (u_offs == 0))
X                        {
X                        bad_key (k);
X                        return (FALSE);
X                        }
X                    else
X                        if (c > '7')
X                            {
X                            bad_key (k);
X                            return (FALSE);
X                            }
X
X            dot_shf = (c - '0') & 7;/* get binary value */
X            l_mask = 7;         /* create bit mask */
X
X            dot_shf <<= (u_roffs * 3);
X            l_mask <<= (u_roffs * 3);
X
X            fill_out (); /* expand buffer if necessary */
X
X            /* save dot position for later */
X            l_ptr = curwp -> w_dotp;
X            d_offs = curwp -> w_doto;
X
X        /* position dot to the byte to be altered */
X            if (intel)
X                {
X                for (i = 0; i < b_per_u; i++)
X                    {
X                    DOT_CHAR(curwp) &= ~((D8) l_mask & 0xff);
X                    DOT_CHAR(curwp) |= (D8) dot_shf & 0xff;
X                    l_mask >>= 8;
X                    dot_shf >>= 8;
X                    move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
X                    }
X                }
X            else
X                {
X                move_ptr (curwp, (long) (b_per_u - 1), TRUE, FALSE, TRUE);
X                                /* move to last byte */
X                for (i = 0; i < b_per_u; i++)
X                    {
X                    DOT_CHAR(curwp) &= ~((D8) l_mask & 0xff);
X                    DOT_CHAR(curwp) |= (D8) dot_shf & 0xff;
X                    l_mask >>= 8;
X                    dot_shf >>= 8;
X                    move_ptr (curwp, -1L, TRUE, FALSE, TRUE);/* step back one byte */
X                    }
X                }
X
X        /* restore dot position */
X            curwp -> w_dotp = l_ptr;
X            curwp -> w_doto = d_offs;
X            forwchar (0, 1, KRANDOM);/* advance the cursor */
X            break;
X
X        case DECIMAL: 
X            fill_out (); /* expand buffer if necessary */
X
X            /* save dot position for later */
X            l_ptr = curwp -> w_dotp;
X            d_offs = curwp -> w_doto;
X
X            bytes = fill_buf (curwp, l_ptr, d_offs, edt_buf, b_per_u);
X        /* if last unit is not full and must be extended */
X            for (; bytes < b_per_u; bytes++)
X                {
X                edt_buf[3] = edt_buf[2];/* shuffle bytes down */
X                edt_buf[2] = edt_buf[1];
X                edt_buf[1] = edt_buf[0];
X                edt_buf[0] = 0;
X                }
X            switch (curwp -> w_fmt_ptr -> r_size)
X                {
X                case BYTES: 
X                    sprintf (text_buf, MSG_03u, (int) (edt_buf[0] & 0xff));
X                    if (!dec_chr_ok (text_buf, max_dec_8, c, u_offs))
X                        {
X                        bad_key (k);
X                        return (TRUE);  /* TRUE so that mask will be same len */
X                        }
X                    sscanf (text_buf, MSG_3u, &i);/* convert back to binary */
X                    l_val = (long) i & 0xff;
X                    break;
X
X                case WORDS: 
X                    l_val = get_int (edt_buf);/* do intel swap */
X                    sprintf (text_buf, MSG_05u, (int) (l_val & 0xFFFF));
X                    if (!dec_chr_ok (text_buf, max_dec_16, c, u_offs))
X                        {
X                        bad_key (k);
X                        return (TRUE);  /* TRUE so that mask will be same len */
X                        }
X                    sscanf (text_buf, MSG_5u, &temp_int);
X                                /* convert back to binary */
X                    l_val = get_int ((char *) & temp_int);/* do intel swap */
X                    break;
X
X                case DWORDS: 
X                    l_val = get_long (edt_buf);/* do intel swap */
X                    sprintf (text_buf, MSG_010lu, l_val);
X                    if (!dec_chr_ok (text_buf, max_dec_32, c, u_offs))
X                        {
X                        bad_key (k);
X                        return (TRUE);  /* TRUE so that mask will be same len */
X                        }
X                    sscanf (text_buf, MSG_lu, &l_val);
X                                /* convert back to binary */
X                    l_val = get_long ((char *) & l_val);/* do intel swap */
X                    break;
X#if RUNCHK
X                default:
X                    writ_echo (ERR_rnd_2);
X                    break;
X#endif
X                }
X            DOT_CHAR(curwp) = (char) l_val & 0xff;
X            for (i = 1; i < b_per_u; i++)
X                {
X                l_val >>= 8;
X                move_ptr (curwp, 1L, TRUE, FALSE, TRUE);/* step forward one byte */
X                DOT_CHAR(curwp) = (char) l_val & 0xff;
X                }
X
X        /* restore dot position */
X            curwp -> w_dotp = l_ptr;
X            curwp -> w_doto = d_offs;
X            forwchar (0, 1, KRANDOM);/* advance the cursor */
X            break;
X
X#if RUNCHK
X        default:
X            writ_echo (ERR_rnd_3);
X            break;
X#endif
X        }
X	/* if cursor has wrapped to the next line then previous line
X		will not be refreshed with WFEDIT so do a WFHARD */
X	if (cur_col > get_curcol(curwp))
X	    lchange (WFHARD);
X	else
X	    lchange (WFEDIT);
X
X    return (TRUE);
X}
X
X/*
X*   Insert one unit of zeros at the current dot position.
X*/
Xbool    insertunit (f, n, k)
X{
X    lchange (WFEDIT);
X    linsert ((R_B_PER_U(curwp) * n), 0);
X    return (TRUE);
X}
X
X/* 
X*   Increase the size of the buffer if necessary.
X*   If dot is at the byte after the last full unit
X*   then add enough bytes to the buffer to create 
X*   a full unit at the end.
X*/  
X
Xbool    fill_out ()
X{
X    long    buf_size, dot_pos, l_val, last_unit;   
X    int     b_per_u;    
X    char    stat, shift;   
X    int     insert_val;
X
X    buf_size = BUF_SIZE(curwp);
X    dot_pos = DOT_POS(curwp);
X    b_per_u = R_B_PER_U(curwp);
X    shift = curwp -> w_disp_shift;       
X    stat = TRUE;    
X    insert_val = 0;
X    last_unit = buf_size & ~((long)(b_per_u - 1));
X    /* there is an even number of units step back one */
X    if (last_unit == buf_size)
X        last_unit -= b_per_u;
X    last_unit += shift;
X
X    /* if dot is one byte past the end of the buffer */
X    if (dot_pos > last_unit)
X        {
X        insert_val = b_per_u;
X        }
X
X    /* if dot is pointed at the end of the buffer */
X    else if (dot_pos == last_unit)
X        {
X        insert_val = b_per_u - (buf_size - last_unit);
X        }
X
X    /* if insert is necessary then do it */
X    if (insert_val != 0)
X        {
X        lchange (WFHARD);
X        move_ptr (curwp, buf_size, TRUE, FALSE, FALSE); /* move dot to end */
X        stat = linsert (insert_val, 0);
X        move_ptr (curwp, dot_pos, TRUE, TRUE, FALSE); /* put dot back */
X        }
X    return (stat);
X}
X
X/*
X*   This checks that an entered character is ok
X*   for the position given.
X*/
X
Xchar    dec_chr_ok (char_buf, max_str, chr, pos)
X
Xchar    chr,
X        pos,
X       *char_buf,
X       *max_str;
X
X{
X    char    i;
X
X    if ((chr < '0') || (chr > '9'))
X        return (FALSE);
X
X    char_buf[pos] = chr;        /* insert typed char */
X
X /* check if number is too big */
X    for (i = 0; max_str[i] != 0; i++)
X        {
X        if (char_buf[i] < max_str[i])
X            break;              /* if char is smaller then must be ok */
X
X        if (char_buf[i] > max_str[i])
X            return (FALSE);     /* val is too large; ERROR */
X        }
X    return (TRUE);
X}
X
X/*
X* Set the rest of the variables for the mode change.
X*/
Xvoid    set_mode_vars ()
X{
X    curwp -> w_disp_shift = 0;  /* shift to 0 when changing mode */
X    curwp -> w_unit_offset = 0; /* go to end of unit */
X    /* if we are in the middle of a search then use the proper format struc */
X    if (read_pat_mode)
X        curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
X        
X    wind_on_dot (curwp);
X    curwp -> w_flag = WFHARD;
X    update ();
X}
X
X/*
X* Change the display mode to ASCII.
X* The default binding is META C-A.
X*/
Xbool    asciimode ()
X{
X    curwp -> w_fmt_ptr = &ascii_fmt;
X    set_mode_vars ();
X    return (TRUE);
X}
X
X/*
X* Change the display mode to EBCDIC.
X* The default binding is META C-E.
X*/
Xbool    ebcdicmode ()
X{
X    curwp -> w_fmt_ptr = &ebcdic_fmt;
X    set_mode_vars ();
X    return (TRUE);
X}
X
X/*
X* Change the display mode to DECIMAL.
X* The default binding is META C-D.
X*/
Xbool    decimalmode ()
X{
X    switch (curwp -> w_fmt_ptr -> r_size)
X        {
X        case BYTES: 
X            curwp -> w_fmt_ptr = &decimal_8_fmt;
X            break;
X        case WORDS: 
X            curwp -> w_fmt_ptr = &decimal_16_fmt;
X            break;
X
X        case DWORDS: 
X            curwp -> w_fmt_ptr = &decimal_32_fmt;
X            break;
X#if RUNCHK
X        default:
X            writ_echo (ERR_rnd_4);
X            break;
X#endif
X        }
X    set_mode_vars ();
X    return (TRUE);
X}
X
X/*
X* Change the display mode to HEXADECIMAL.
X* The default binding is META C-H.
X*/
Xbool    hexmode ()
X{
X    switch (curwp -> w_fmt_ptr -> r_size)
X        {
X        case BYTES: 
X            curwp -> w_fmt_ptr = &hex_8_fmt;
X            break;
X        case WORDS: 
X            curwp -> w_fmt_ptr = &hex_16_fmt;
X            break;
X        case DWORDS: 
X            curwp -> w_fmt_ptr = &hex_32_fmt;
X            break;
X#if RUNCHK
X        default:
X            writ_echo (MSG_rnd_5);
X            break;
X#endif
X        }
X    set_mode_vars ();
X    return (TRUE);
X}
X
X/*
X* Change the display mode to OCTAL.
X* The default binding is META C-O.
X*/
Xbool    octalmode ()
X{
X    switch (curwp -> w_fmt_ptr -> r_size)
X        {
X        case BYTES: 
X            curwp -> w_fmt_ptr = &octal_8_fmt;
X            break;
X
X        case WORDS: 
X            curwp -> w_fmt_ptr = &octal_16_fmt;
X            break;
X
X        case DWORDS: 
X            curwp -> w_fmt_ptr = &octal_32_fmt;
X            break;
X#if RUNCHK
X        default:
X            writ_echo (ERR_rnd_6);
X            break;
X#endif
X        }
X    set_mode_vars ();
X    return (TRUE);
X}
X
X/*
X* Change the display mode to BINARY.
X* The default binding is META C-B.
X*/
Xbool    binarymode ()
X{
X    switch (curwp -> w_fmt_ptr -> r_size)
X        {
X        case BYTES: 
X            curwp -> w_fmt_ptr = &binary_8_fmt;
X            break;
X        case WORDS: 
X            curwp -> w_fmt_ptr = &binary_16_fmt;
X            break;
X        case DWORDS: 
X            curwp -> w_fmt_ptr = &binary_32_fmt;
X            break;
X#if RUNCHK
X        default:
X            writ_echo (ERR_rnd_7);
X            break;
X#endif
X        }
X    set_mode_vars ();
X    return (TRUE);
X}
X
X/*
X* Change the display shift.
X* Circularly rotate through display shift of 0 through 3.
X* This value is used to shift the display by the designated number of bytes.
X* This is used to cause WORD and DWORD values to be calculated
X* from the correct offset.
X*/
Xbool dispshift (f, n, k)
X{
X    char    mode,
X            size;
X
X    if (read_pat_mode)
X        return (TRUE);  /* no shift is allowed in search mode */    
X
X    mode = curwp -> w_fmt_ptr -> r_type;
X    size = curwp -> w_fmt_ptr -> r_size;
X
X    if (((mode == HEX) ||
X                (mode == DECIMAL) ||
X                (mode == BINARY) ||
X                (mode == OCTAL)) &&
X            (size != BYTES))
X        {
X        if ((size == WORDS) &&
X                (curwp -> w_disp_shift >= 1))
X            {                   /* roll over on words */
X            curwp -> w_disp_shift = 0;
X            }
X        else
X            if ((size == DWORDS) &&
X                    (curwp -> w_disp_shift >= 3))
X                {               /* roll over on double words */
X                curwp -> w_disp_shift = 0;
X                }
X            else
X                {
X                curwp -> w_disp_shift++;/* increment shift */
X                }
X        }
X    else
X        {
X        curwp -> w_disp_shift = 0;/* set to no shift */
X        }
X    move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
X    wind_on_dot (curwp);
X    curwp -> w_flag = WFHARD;   /* force full window refresh */
X    return (TRUE);
X}
X
X/*
X* Delete forward. This is real
X* easy, because the basic delete routine does
X* all of the work. Watches for negative arguments,
X* and does the right thing. If any argument is
X* present, it kills rather than deletes, to prevent
X* loss of text if typed with a big argument.
X* Normally bound to "C-D".
X*/
Xchar    forwdel (f, n, k)
X{
X    char    s;
X
X    if (n < 0)
X        return (backdel (f, -n, KRANDOM));
X    
X    s = FALSE;
X    if (R_SIZE(curwp) == BYTES)
X        {
X        if (f != FALSE)
X            {
X        /* Really a kill.       */
X            if ((lastflag & CFKILL) == 0)
X                kdelete ();
X            thisflag |= CFKILL;
X            }
X        s = ldelete (n, f);
X        curwp -> w_unit_offset = 0;
X        }
X    return (s);
X}
X
X
X/*
X* Delete backwards. This is quite easy too,
X* because it's all done with other functions. Just
X* move the cursor back, and delete forwards.
X* Like delete forward, this actually does a kill
X* if presented with an argument.
X*/
Xchar    backdel (f, n, k)
X{
X
X    int     u_off;
X    char    s;
X
X    if (n < 0)
X        return (forwdel (f, -n, KRANDOM));
X
X    s = FALSE;
X    if (R_SIZE(curwp) == BYTES)
X        {
X        u_off = curwp -> w_unit_offset;
X        curwp -> w_unit_offset = 0;
X        if ((s = backchar (f, n * R_CHR_PER_U(curwp), KRANDOM)) == TRUE)
X            {
X            s = ldelete (n, f);
X            if (f != FALSE)
X                {
X                /* Really a kill.       */
X                if ((lastflag & CFKILL) == 0)
X                    kdelete ();
X                thisflag |= CFKILL;
X                }
X            }
X        curwp -> w_unit_offset = u_off;
X        }
X    return (s);
X}
X
X
X/*
X* Change the size of the display unit to BYTE.
X* Adjust byte shift to the allowable range.
X* Normally bound to "META-1".
X*/
Xbool dispsize1 ()
X{
X    curwp -> w_disp_shift = 0;  /* shift to 0 when changing size */
X    curwp -> w_unit_offset = 0; /* go to end of unit */
X
X    switch (R_TYPE(curwp))
X        {
X        case OCTAL: 
X            curwp -> w_fmt_ptr = &octal_8_fmt;
X            break;
X
X        case DECIMAL: 
X            curwp -> w_fmt_ptr = &decimal_8_fmt;
X            break;
X
X        case HEX: 
X            curwp -> w_fmt_ptr = &hex_8_fmt;
X            break;
X
X        case BINARY: 
X            curwp -> w_fmt_ptr = &binary_8_fmt;
X            break;
X
X        default:
X            return (TRUE);
X            break;
X        }
X
X    /* if we are in the middle of a search then use the proper format struc */
X    if (read_pat_mode)
X        curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
X        
X    move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
X    wind_on_dot (curwp);
X    curwp -> w_flag = WFHARD;
X    update ();
X    return (TRUE);
X}
X
X/*
X* Change the size of the display unit to WORD.
X* Adjust byte shift to the allowable range.
X* Normally bound to "META-2".
X*/
Xbool dispsize2 ()
X{
X    curwp -> w_disp_shift = 0;  /* shift to 0 when changing size */
X    curwp -> w_unit_offset = 0; /* go to end of unit */
X
X    switch (R_TYPE(curwp))
X        {
X        case OCTAL: 
X            curwp -> w_fmt_ptr = &octal_16_fmt;
X            break;
X
X        case DECIMAL: 
X            curwp -> w_fmt_ptr = &decimal_16_fmt;
X            break;
X
X        case HEX: 
X            curwp -> w_fmt_ptr = &hex_16_fmt;
X            break;
X
X        case BINARY: 
X            curwp -> w_fmt_ptr = &binary_16_fmt;
X            break;
X
X        default:
X            return (TRUE);
X            break;
X        }
X
X    /* if we are in the middle of a search then use the proper format struc */
X    if (read_pat_mode)
X        curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
X        
X    move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
X    wind_on_dot (curwp);
X    curwp -> w_flag = WFHARD;
X    update ();
X    return (TRUE);
X}
X
X/*
X* Change the size of the display unit to DOUBLE WORD.
X* Adjust byte shift to the allowable range.
X* Normally bound to "META-4".
X*/
Xbool dispsize4 ()
X{
X    curwp -> w_disp_shift = 0;  /* shift to 0 when changing size */
X    curwp -> w_unit_offset = 0; /* go to end of unit */
X
X    switch (R_TYPE(curwp))
X        {
X        case OCTAL: 
X            curwp -> w_fmt_ptr = &octal_32_fmt;
X            break;
X
X        case DECIMAL: 
X            curwp -> w_fmt_ptr = &decimal_32_fmt;
X            break;
X
X        case HEX: 
X            curwp -> w_fmt_ptr = &hex_32_fmt;
X            break;
X
X        case BINARY: 
X            curwp -> w_fmt_ptr = &binary_32_fmt;
X            break;
X
X        default:
X            return (TRUE);
X            break;
X        }
X
X    /* if we are in the middle of a search then use the proper format struc */
X    if (read_pat_mode)
X        curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
X        
X    move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
X    wind_on_dot (curwp);
X    curwp -> w_flag = WFHARD;
X    update ();
X    return (TRUE);
X}
X
X/*
X* Display byte swaped.   This command causes the bytes
X* that are displayed in WORD and DWORD mode to be swaped
X* in the way that the INTEL microprocessors do it.
X*/
Xbool dispswapbyte (f, n, k)
X{
X    if ((curwp -> w_fmt_ptr -> r_size) == BYTES)
X        return (TRUE);
X
X    if (curwp -> w_intel_mode)
X        curwp -> w_intel_mode = FALSE;
X    else
X        curwp -> w_intel_mode = TRUE;
X
X    curwp -> w_flag = WFHARD;
X    update ();
X    return (TRUE);
X}
X
X/*
X* Yank text back from the kill buffer. This
X* is really easy. All of the work is done by the
X* standard insert routines. All you do is run the loop,
X* and check for errors. 
X* An attempt has been made to fix the cosmetic bug
X* associated with a yank when dot is on the top line of
X* the window (nothing moves, because all of the new
X* text landed off screen).
X*/
Xbool yank (f, n, k)
X{
X    register int    c;
X    register int    i;
X    register    LINE * lp;
X
X    if (n < 0)
X        return (FALSE);
X    while (n--)
X        {
X        i = 0;
X        while ((c = kremove (i)) >= 0)
X            {
X            if (linsert (1, c) == FALSE)
X                return (FALSE);
X            ++i;
X            }
X        }
X    curwp -> w_flag |= WFHARD;
X    return (TRUE);
X}
X
X/*
X*   Link windows.   pvr
X*   This function toggles the window linking function.
X*   When linking is enabled all windows that look at 
X*   the same buffer will be forced to have the same 
X*   dot position.   Each window is then moved to be
X*   positioned on the dot.   Thus when a user moves
X*   arround a buffer all other views into that buffer 
X*   will follow.
X*/
X
Xbool linkwind ()
X
X{
X    char    buf[80];
X
X    if (curwp -> w_bufp -> b_flag & BFLINK)
X        {
X        curwp -> w_bufp -> b_flag &= ~(BFLINK & 0xff);
X        sprintf (buf, MSG_lnk, curwp -> w_bufp -> b_bname, MSG_unlink);
X        }
X    else
X        {
X        curwp -> w_bufp -> b_flag |= BFLINK;
X        sprintf (buf, MSG_lnk, curwp -> w_bufp -> b_bname, MSG_link);
X        }
X    writ_echo (buf);
X    return (TRUE);
X}
X/*
X*   Print all bad keys to the screen and beep 
X*/
Xvoid    bad_key (key)
Xint     key;
X    {
X    char    buf[80], buf1[40];
X
X    ttbeep ();
X    sprintf (buf, MSG_bad_key);
X	keyname (&buf[strlen (buf)], key);
X	sprintf (&buf[strlen (buf)], ", %X", key);
X    writ_echo (buf);
X    }
END_OF_FILE
if test 30423 -ne `wc -c <'random.c'`; then
    echo shar: \"'random.c'\" unpacked with wrong size!
fi
chmod +x 'random.c'
# end of 'random.c'
fi
echo shar: End of archive 7 \(of 10\).
cp /dev/null ark7isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
>>>>>>>>>>>>>>>> Peter Reilley ..... pvr@wang.com <<<<<<<<<<<<<<<<<<<<<<<
                     Well, that about says it.

pvr@wang.com (Peter Reilley) (06/06/91)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 8 (of 10)."
# Contents:  beav1.doc
# Wrapped by pvr@elf on Thu Mar 14 08:16:48 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'beav1.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'beav1.doc'\"
else
echo shar: Extracting \"'beav1.doc'\" \(32050 characters\)
sed "s/^X//" >'beav1.doc' <<'END_OF_FILE'
X
X
X
X
X
X
X
X
X                               BEAV
X                     Binary Editor And Viewer
X
X                      Manual Copyright 1991
X
X                           Version 1.20
X                          March 13, 1991
X
X                                By
X                          Peter Reilley
X                         19 Heritage Cir.
X                        Hudson, N.H. 03051
X                           pvr@wang.com
X
X             BEAV source and executable can be freely
X             distributed for non-commercial purposes.
X 
X
X
X
X
X
X
X
X
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X
X                        Table of Contents
X
X1.    Introduction
X
X2.    Overview
X 2.1       Terms and Definitions
X 2.2       The Screen Format
X 2.3       Display Modes
X 2.4       Commands
X 2.5       Buffers
X 2.6       Files
X 2.7       Key Binding
X 2.8       Configuration
X
X3.    Command Description
X 3.1       Help
X 3.2       Cursor Movement
X 3.3       Buffer Management
X 3.4       File Management
X 3.5       Window Management
X 3.6       Inserting and deleting
X 3.7       Search and Replace Commands
X 3.8       Exiting BEAV
X 3.9       Printing
X 3.10      Keyboard Macros
X 3.11      Key Binding
X 3.12      Special Functions
X
X4.    Alphabetical list of commands by name
X
X5.    Alphabetical list of commands by default key binding
X
X6.    Release notes
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 2  -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X
X1.0   Introduction
X
X      BEAV  is  an  editor that brings the features of a powerful
Xfull screen editor to the editing of binary files.    It  is  the
Xonly editor that I know of that does that.
X
X      When  you  need  to edit a non-text file you generally have
Xtwo choices; a text editor or a  file  zap  type  editor.    Each
Xchoice has significant disadvantages.
X
X      Text  editors  expect the file to be formatted in a certain
Xway.   At a minimum they expect that all lines be  terminated  by
Xa  carriage  return  or  line  feed  and  be  limited  in length.
XThere is no line length limit  with  BEAV.    Most  text  editors
Xget  confused  by  bytes that are outside of the normal range (20
Xto 7E HEX).   In BEAV no  special  characters  such  as  carriage
Xreturn  or  line  feed  affect  the  display aside from producing
Xtheir numeric value.   BEAV can  edit  any  file  no  matter  the
Xformat.
X
X      The  other  choice  is  to use a file zap type editor which
Xcan edit a binary file without  difficulty.   These  editors  are
Xoften  very  limited  in  their features and capabilities.   Most
Xfile zap programs can edit a file only in HEX  or  ASCII.    They
Xgenerally  operate  on  a  sector  basis and because of this they
Xcannot insert or delete data in the middle of the file.
X
X      All these limits are eliminated in BEAV.   You can  edit  a
Xfile  in  HEX,  ASCII,  EBCDIC, OCTAL, DECIMAL, and BINARY.   You
Xcan search or search and replace in any of  these  modes.    Data
Xcan  be  displayed in BYTE, WORD, or DOUBLE WORD formats.   While
Xdisplaying WORDS or DOUBLE WORDS the data  can  be  displayed  in
XINTEL's  or  MOTOROLA's  byte  swap  format.   Data of any length
Xcan be inserted at any point in the file.   The  source  of  this
Xdata  can  be the keyboard, another buffer, or a file.   Any data
Xthat is  being  displayed  can  be  sent  to  a  printer  in  the
Xdisplayed  format.    Files  that  are  bigger than memory can be
Xhandled.
X
X      Some users may recognize the similarity to the  EMACS  text
Xeditor  that  was  written  by Richard Stallman at MIT.   This is
Xnot a coincidence.   I attempted to keep  as  much  of  the  user
Xinterface   and   functionality   as   possible  given  the  very
Xdifferent tasks of EMACS and BEAV.
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 3  -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X2.    Overview
X 2.1       Terms and Definitions
X
X      Throughout this  manual  certain  terms  will  be  used  to
Xdescribe the operation and structure of BEAV.
X
X      The  data  that BEAV is editing is held in a buffer that is
Xstructured as a byte  stream.    There  are  many  commands  that
Xaffect  the  way  that  this  byte  stream is displayed on to the
Xscreen.   Whatever  display  mode  is  chosen  the  data  in  the
Xbuffer is not effected, only the presentation.
X
X      One  such  choice  is  to display the data as bytes, words,
Xor double words.   That is; 8 bit values, 16 bit  values,  or  32
Xbit  values.    Whatever choice is made the value of the selected
Xsize will be displayed.   These values are referred to  as  units
Xin  this  manual.    Thus  the 'delete-forw-unit' command deletes
Xthe  unit  under  the  cursor.    If  32  bit  units  are   being
Xdisplayed then 4 bytes will be deleted.
X
X      Many  commands  in  BEAV  start  by  pressing  the 'ESCAPE'
Xkey.   When this manual refers to a command  that  requires  that
Xthe   'ESCAPE'  key  be  pressed  it  will  be  abbreviated  with
X'Esc'.   Another frequently used key  stroke  to  start  commands
Xis  'CONTROL  X'.    This  in  done by pressing the 'CONTROL' key
Xthen pressing the 'X' key at the  same  time.    In  this  manual
Xthis  will  be  abbreviated  by 'Ctl-X'.    Many commands contain
Xother  control  characters  and   these   will   be   abbreviates
Xsimilarly.    Thus  the  'insert-unit'  command will be listed as
X'Ctl-X I'.   This will be entered by  pressing  the  CONTROL  key
Xand  while  holding  it  hitting the 'X' key, release the CONTROL
Xkey then hit the 'I' key.
X
X 2.2       The Screen Format
X      BEAV presents information  to  the  user  in  a  number  of
Xareas.    The  first  is the window.   There will be at least one
Xwindow displayed  on  the  screen  at  all  times.    The  window
Xconsists  of  two  areas.   The first is the display area.   This
Xis where the data that is in the buffer is displayed.    Most  of
Xthe  time  the cursor will be in this area, as this is where most
Xediting is done.   Each line  in  the  display  area  will  start
Xwith  a  number  that  indicates  the  offset into the buffer for
Xthis line of data.   At the bottom of the display area  for  each
Xwindow is the status line.
X
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 4  -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X      The  status  line  presents  the  user  with  a  number  of
Xspecific  pieces  of information.   The first is the program name
Xwhich is "BEAV".   Next  there  are  some  flags  indicating  the
Xstatus of this particular buffer.
X
X      The  first  flag  indicates  if the buffer has been damaged
Xby a memory allocation failure.   If there  is  a  '?'  then  the
Xbuffer  is  bad,  otherwise  there will be a space.   Bad buffers
Xare set to read only.
X
X      The next flag indicates if  the  buffer  has  been  changed
Xand  will  need  to  be  written  out  if  the  changes are to be
Xsaved.   This flag is a '*'  if  the  buffer  has  been  changed,
Xotherwise there will be a space.
X
X      The  next  flag  indicates  insert/overstrike mode; 'I' for
Xinsert, 'O' for overstrike.   This is only  meaningful  in  ascii
Xor ebcdic mode.
X
X      Then  the  buffer  name  followed  by  the  file  name.   A
Xwindow can be in read only, read/write, or read/write  with  size
Xlock.     These   will  be  displayed  as  [RO],  [RW],  or  [WL]
Xrespectively.   If auto-update  is  enabled  then  [AU]  will  be
Xdisplayed.
X
X      Next  the  cursor  position  in  bytes  and  the  character
Xposition  within  the unit.   The next piece of information gives
Xthe format that the data  is  being  displayed  in;  HEX,  OCTAL,
XDECIMAL,  BINARY,  ASCII,  EBCDIC.    If  a data mode is selected
Xthen the size in bytes (1, 2, 4) is displayed.   If the  data  is
Xbeing   displayed   in  Intel  mode  then  the  swapped  flag  is
Xdisplayed, 'S'.   Lastly the byte  shift  is  displayed;  0  only
Xfor  8  bit  data, 0 or 1 for 16 bit data, or 0, 1, 2 or 3 for 32
Xbit data.
X
X      There can be multiple windows on the  screen  at  the  same
Xtime but each window will have a status line at the bottom.
X
X      The  very  bottom  line  on  the screen is the prompt line.
XThis is where you enter data that BEAV requests.    If  you  want
Xto  edit  a  new  file  you  would type 'Ctl-X Ctl-V', BEAV would
Xrespond with "Visit file:"  on  the  prompt  line.    The  cursor
Xwould  be  positioned  after  the  prompt.   You would then enter
Xthe name of the file that you wished to edit.
X
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 5  -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X      If you entered the command by mistake, you  can  abort  the
Xoperation  by  typing  a  'Ctl-G'.    'Control  G' is a universal
Xabort command  and  can  be  used  anywhere.    If  you  want  to
Xperform  a  search  you  will  enter  the  search  string on this
Xline.   When you have  entered  the  information  that  BEAV  has
Xrequested  hit  'Return'  and  the  cursor  will  return  to it's
Xoriginal position in the window display area.   The  prompt  line
Xis also where error messages are displayed.
X
X
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 6  -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X 2.3       Display Modes
X
X      The  data  in  the  buffer  can be displayed in a number of
Xformats.   First  there  is  the  display  mode.    This  can  be
Xeither; HEXADECIMAL, DECIMAL, OCTAL, BINARY, ASCII, or EBCDIC.
X
X      If  ASCII  or  EBCDIC  mode is chosen then each byte in the
Xbuffer will be converted to it's ASCII or  EBCDIC  character  and
Xdisplayed.    Bytes  that  are  outside of the standard character
Xset  will  be  displayed  as  a  dot.    Each  line  will  be  64
Xcharacters long.   The  byte  value  for  "carriage  return"  and
X"line   feed"   will   be   displayed  as  a  dot  as  any  other
Xnon-printable characters.
X
X      Within HEXADECIMAL, DECIMAL, OCTAL, or  BINARY  format  the
Xdata  can  be  displayed in 8, 16 or 32 bit values.   If 16 or 32
Xbit values are displayed  the  user  can  choose  to  view  these
Xvalues  in  either  the Intel format or the Motorola format.   If
XIntel format is chosen then the first byte in each  unit  is  the
Xleast  significant  byte  when the value is calculated.   Thus in
Xhex 32 bit mode  a  byte  string  of  "32  7A  9F  10"  would  be
Xdisplayed  as  "109F7A32".    If  Motorola  format is chosen this
Xvalue would be displayed as "327A9F10".
X
X      There is another display format  choice  that  affects  the
X16  or  32  bit  formats.   This is called shift.   The shift can
Xbe 0 or 1 for 16 bit modes, or 0, 1,  2,  3  for  32  bit  modes.
XShift  moves  the  zero  point reference for the buffer up by the
Xselected value.   The default is zero shift.    If  a  buffer  is
Xdisplaying the following 32 bit hex data;
X
X           "12345678 2F4792AF 673DFEA1 88551199"
X
Xwith the shift at 0.   Changing shift to 1 will produce;
X
X           "3456782F 4792AF67 3DFEA188 55119955"
X
XThe  data  has  been slid down toward the beginning of the buffer
Xby one byte.   This has not changed the data  in  the  buffer  at
Xall,  it  has only affected the way that the data is presented on
Xthe screen.   This is useful  when  looking  at  WORD  or  DOUBLE
XWORD data that is not aligned on two or four byte boundaries.
X
X      When  BEAV  is  first started or a new window is opened the
Xdefault format is HEXADECIMAL BYTES.
X
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 7  -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X 2.4       Commands
X
X      Commands  are  the  means  that  the  user   controls   the
Xoperation  of  BEAV.   A command can be given by using one of two
Xmethods.   The first is to use the key binding.
X
X      A command can have one or  more  associated  key  bindings.
XIt  can  also  have  no key binding.   There are a set of default
Xkey bindings that BEAV comes configured with.   The  current  set
Xof  key  bindings  can be seen by using the 'help' command.   The
X'help' command is 'Esc ?' or Function  Key  1  'F1'  on  the  IBM
XPC.    The  help  buffer can be scrolled by using the up and down
Xarrow keys.   A printed copy may be  obtained  by  going  to  the
Xbottom  of  the help buffer using the 'move-to-end' command ('Esc
X>' or the 'End' key).    Then  issue  the  'print-mark-to-cursor'
Xcommand  ('Esc  P' or 'Ctl-Print') and enter 'PRN' or a file name
Xwhen prompted with "Print to:".   This  will  output  the  entire
Xhelp  buffer  to a printer connected to the parallel interface or
Xthe specified file.
X
X      The second method of  issuing  a  command  is  to  use  the
X'extended-command'  command  (Esc  X).    You  are prompted for a
Xcommand name that you want to execute.   This  method  is  useful
Xfor executing commands that have no key binding.
X
X
X 2.5       Buffers
X
X      Buffers  are  the  in  memory  storage for all data editing
Xand viewing.   Each buffer has a name that appears  in  the  mode
Xline.    Buffers  generally  have  a file name that is associated
Xwith them.   The file name also appears in the mode  line.    The
Xbuffer  name  and  the  file  name are independent but the buffer
Xname defaults to the file name.
X
X      The buffer name is used to  refer  to  a  specific  buffer.
XThe  'change-buffer'  ('Ctl-X  B')  command will prompt you for a
Xbuffer name.   After you enter a buffer  name  that  buffer  will
Xbe  displayed  in  the  current  window.    If  there  is no such
Xbuffer, one will be created and displayed (it will be empty).
X
X      When BEAV is run  with  a  file  name  as  a  command  line
Xparameter,  the  file is read into a new buffer.  The buffer name
Xwill be made the same as the file name.   The file name  is  only
Xused  when  the  buffer  is  saved.   If the file name is changed
Xusing the 'buffer-set-file-name'  ('Ctl-X  Ctl-F')  command  then
Xwhen the buffer is saved it will be saved to the new file.
X
X 
X 
X 
X 
X 
X
X
X                              - 8  -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X      Buffers  are  dynamically  allocated.   They grow or shrink
Xas the size of the data they contain changes.   The  buffer  size
Xcan  be  frozen  using  the  'buffer-size-lock'  ('Ctl-X  Ctl-L')
Xcommand.    This  prevents  inserting  or  deleting data from the
Xbuffer but data can be modified.
X
X      Buffers continue to  exist  even  if  they  are  not  being
Xdisplayed.    Buffers  are  saved  in  a  linked list that can be
Xstepped through using the 'change-to-next-buffer'  ('Esc  +')  or
X'change-to-prev-buffer'    ('Esc    -')    commands.     If   the
X'change-to-next-buffer' command is given  then  the  next  buffer
Xin the list is displayed in the current window.
X
X
X 2.6       Files
X
X      Files  are  the  means  of storing data on disk.   Files or
Xsegments of  files  can  be  loaded  into  BEAV  for  editing  or
Xviewing.    The  file on the disk has not been changed until BEAV
Xdoes a save to that file.   When a save to a  file  is  performed
Xthe original file contents in saved in a ".bak" file.
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 9  -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X
X 2.7  Key Binding
X
X      All  commands  in  BEAV  have  a command name and a default
Xkey binding.   The bindings  may  be  changed  to  suit  personal
Xpreference  by  using  the 'bind-to-key' ('Esc K') command.   The
Xcurrent binding of a key sequence can be displayed by  using  the
X'binding-for-key' ('Ctl-X ?') command.
X
X      Key  bindings  can  be  loaded  automatically  from  a file
Xnamed "beavrc".   This file must be in a directory  specified  by
Xthe  PATH  environment variable.   When BEAV is started this file
Xis read and the bindings are loaded.    This  file  is  a  simple
Xtext file and can be edited to make changes.
X
X      The  beavrc  file  contains  three  columns.   The first is
Xthe function name to be bound.   The second is the  key  sequence
Xthat  is  bound  to  that  function.   The third is a number that
Xdefines the key code.   Then the beavrc  file  is  read  in  only
Xthe first and third columns are used.
X
X      The  simplest  way  to  create  a  valid  beavrc file is to
Xfirst bind the key codes  to  the  desired  functions  using  the
Xbind-to-key  command.    Next  display  the current bindings in a
Xwindow using the help command (Esc ?).    Now  save  that  buffer
Xto  a  file with the file-write command (Ctl-X Ctl-W).   You will
Xbe prompted for a file name.    This  is  a  valid  beavrc  file.
XYou  may  want  to  edit  the beavrc file to remove the commented
Xlines, those beginning with #, to make it load faster.
X
X      On unix systems there can be  multiple  beavrc  files,  one
Xfor  each  terminal type.   This is accomplished by appending the
XTERM variable to beavrc.   Thus if you use both  a  vt100  and  a
Xwyse60   terminal,   you   could   have   a   beavrc.wy60  and  a
Xbeavrc.vt100  bindings  file.    When  your  TERM   variable   is
XTERM=wy60  then  the beavrc.wy60 bindings file will be used.   If
Xthere is no beavrc.wy60 file then the beavrc file will be used.
X
X
X 2.8  Configuration
X
X      When the MSDOS version of BEAV run it detects  whether  the
Xsystem  is  an  IBM  PC  or a clone.   If a PC is detected then a
Xset of key bindings  that  use  the  10  function  keys  and  the
Xrelevant   keypad  keys  are  loaded.    If  the  system  is  not
Xrecognized then only the standard bindings are loaded.
X
X 
X 
X 
X 
X 
X 
X
X
X                              - 10 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X      If a PC is detected the screen is managed  by  making  BIOS
Xlevel  calls  that  enhance  performance.   Otherwise, the screen
Xis controlled by making ANSI compatible calls  to  the  operating
Xsystem.    This  is  much slower but is not sensitive to hardware
Xconfiguration.   This requires that  non-standard  MSDOS  systems
Xsupport  ANSI  display  controls.    The  following  ANSI  escape
Xsequences are used;
X
X      Position cursor          ESC [ <row> ; <column> H
X
X      Erase to end of line     ESC [ 0 K
X
X      Erase to end of page     ESC [ 0 J
X
X      Normal video             ESC [ 0 m
X
X      Reverse video            ESC [ 7 m
X
X      On  unix  systems  the  termcap  library  is  used.    This
Xrequires that the TERM environment variable be set correctly.
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 11 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X
X3.    Command Description
X
X      This  section  describes  all  BEAV  commands  as  to their
Xfunction and any side effects that they  may  have.    The  first
Xline  of  each  description  of  a  command  will  begin with the
Xdefault key binding then the command name and  follows  with  the
Xkey binding for a PC for the MSDOS version.
X
X 3.1  Help
X
X      This  command  returns information that will aid in the use
Xof BEAV.
X
X      Esc ?          help                     F1
X
X      A new window is opened  by  splitting  the  current  window
Xthen  all  current  key  bindings are displayed.   This buffer is
Xlarger than can be shown at one time  and  must  be  scrolled  up
Xand  down  to  see all entries.    All commands that do not alter
Xdata can be used to move  around  and  search  the  help  buffer.
XTo   leave  the  help  buffer  use  the  'window-delete'  command
X('Ctl-X 0').
X
X      Lines  that  begin  with  the  comment  character  (#)  are
Xcommands that have the  default  bindings.    Lines  without  the
Xcomment  character  have  been bound by the user or by processing
Xa beavrc file.    The  comment  character  helps  in  creating  a
Xbeavrc   file  by  identifying  only  those  bindings  that  have
Xchanged.
X
X
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 12 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X 3.2  Cursor Movement
X
X      There are  a  number  of  commands  that  move  the  cursor
Xaround  the  current window.   If the cursor bumps the top or the
Xbottom  of  the  window  the  position  of  the  window  will  be
Xadjusted so as to keep the cursor within the bounds.    When  the
Xwindow  is  moved  in response to cursor movements it is moved by
Xabout one third of the window size.   This  improves  performance
Xby reducing the number of window moves.
X
X      Ctl-P          move-back-line           North (up arrow)
X      Ctl-N          move-forw-line           South (down arrow)
X
X      These  commands  move  the  cursor  up one line or down one
Xline.   If the cursor is on the top line  in  the  buffer  and  a
X'move-back-line'  command  is  given  the cursor will jump to the
Xbeginning of the first unit in the buffer.    If  the  cursor  is
Xon  the  last  line of the buffer and a 'move-forw-line' is given
Xthe cursor will move to the last unit in the buffer.
X
X      Ctl-F          move-forw-char           East (right arrow)
X      Ctl-B          Move-back-char           West (left arrow)
X
X      These commands move the cursor forward or backward  in  the
Xcurrent  line.    If  the cursor is at the first character in the
Xfirst unit of  the  line  and  the  'move-back-char'  command  is
Xgiven  then  the  cursor  will  wrap to the last character of the
Xprevious line.   If the cursor is at the last  character  of  the
Xlast  unit  in  the  current  line then it will wrap to the first
Xcharacter of the next line.
X
X      Esc F          move-forw-unit           Ctl-East
X      Esc B          move-back-unit           Ctl-West
X
X      These commands are similar to the above set but  they  move
Xthe  cursor  by  units  rather  than  characters.    The  command
X'move-forw-unit'   will   position   the   cursor  to  the  first
Xcharacter of the next unit.   The command  'move-back-unit'  will
Xmove the cursor to the first character of the previous unit.
X
X      Ctl-V          move-forw-page           PageUp
X      Esc V          move-back-page           PageDown
X
X      These  commands  move  the  move  the data in the window by
Xthe number of lines in the window less  one.    The  cursor  will
Xstay  in  the same position relative to the window as the data is
Xmoved.
X
X 
X 
X 
X 
X 
X
X
X                              - 13 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X      Esc <          move-to-beginning        Home
X      Esc >          move-to-end              End
X
X      Move the cursor to the beginning or the end of the buffer.
X
X      Ctl-X G        move-to-byte             F9
X
X      Prompt for a byte offset, then go to that position  in  the
Xcurrent buffer.
X
X      Ctl-X Ctl-N    move-window-down         Ctl-Z
X      Ctl-X Ctl-P    move-window-up           Esc Z
X
X      Move  the  buffer  in  the  window  up or down by one line.
XThis does not effect the cursor until it hits the top  or  bottom
Xof the window.
X
X      Esc .          mark-set                 F2
X
X      Set  the  mark  position  to  the  current cursor position.
XThe mark position is remembered even for  nonactive  windows  and
Xbuffers.
X
X      Ctl-X Ctl-X    swap-cursor-and-mark
X
X      The  position  of  the  cursor and the position of the mark
Xare swapped.
X
X      Esc L          window-link
X
X      This command causes all windows  that  are  displaying  the
Xcontents   of   the  current  buffer  to  have  the  same  cursor
Xposition.   Thus  if  one  window  is  scrolled  then  all  other
Xwindows  that  display that buffer are scrolled so as to keep the
Xcursor in the window.
X
X      Ctl-X =        show-position
X
X      The current  position  of  the  cursor  and  the  mark  are
Xdisplayed.    The  buffer  size, file size and file name are also
Xshown.
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 14 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X 3.3  Buffer Management
X
X      Buffers store all data that is  being  edited.    The  only
Xlimit  to  the  number  of  buffers  is  the  size  of  available
Xmemory.    If  a  file  is  loaded  into  a  buffer  and there is
Xinsufficient memory to hold the entire  file,  then  it  will  be
Xloaded  until  memory is exhausted.   The buffer will then be set
Xto read only mode.
X
X      Ctl-X Ctl-B    buffers-display          Ctl-F1
X
X      A new window is opened and a list of all  buffers  in  BEAV
Xis  displayed.    The  list  contains  the  buffer name, the file
Xname (if it exists), the buffer size,  and  a  state  flag.    If
Xthe  list  is too large for the window, you can go to that window
Xand scroll the list.
X
X      Ctl-X B        change-buffer            Ctl-F2
X
X      This command prompts  you  for  a  buffer  name.    If  you
Xenter  the  name  of  an  existing  buffer,  that  buffer will be
Xdisplayed in the current window.   If the  name  does  not  match
Xan   existing   buffer,   a   new  buffer  will  be  created  and
Xdisplayed.   This buffer will be empty  and  will  have  no  file
Xname.
X
X      Esc +          change-to-next-buffer    Ctl-F4
X      Esc -          change-to-prev-buffer    Ctl-F5
X
X      The  next  or  the  previous  buffer  in the buffer list is
Xdisplayed in the current window.   This does not  effect  buffers
Xthat are displayed in other windows.
X
X      Esc G          move-to-buffer-split
X
X      Prompt  for  a buffer name.   Then split the current window
Xand display that buffer, creating it if necessary.
X
X      Esc Ctl-N      buffer-set-name          Esc Ctl-N
X
X      The current buffer name is changed to  the  name  that  you
Xenter.   This does not effect the file name.
X
X      Ctl-X Ctl-F    buffer-set-file-name     Ctl-F7
X
X      The  file  name  of  the  current  buffer is changed to the
Xname that you enter.   This does not affect the buffer name.
X
X 
X 
X 
X 
X 
X
X
X                              - 15 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X      Ctl-X K        kill-buffer              Ctl-F3
X
X      This command prompts you for a buffer name.    This  buffer
Xis  then  deleted.    If  the buffer is currently being displayed
Xyou are prompted for  conformation.    If  the  buffer  has  been
Xchanged you are again prompted for conformation.
X
X      Ctl-X Ctl-L    buffer-size-lock
X
X      The  buffer  size  is  prevented from being changed.   Data
Xcan be edited but only by changing  the  existing  data.    If  a
Xbuffer  is  copied  into  a size-locked buffer the operation well
Xbe successful but will overwrite existing  data.    This  command
Xtoggles between locked and unlocked.
X
X      Esc Y          yank-buffer              Ctl-F6
X
X      Data  from  one  buffer is inserted into the current buffer
Xat the cursor position.   You are prompted for the  name  of  the
Xbuffer to copy from.
X
X      Esc O          save-mark-to-cursor
X
X      Prompt  for  a buffer name.   Create a new buffer with that
Xname and write the data from the mark to  the  cursor  into  that
Xbuffer.
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 16 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X 3.4  File Management
X
X      These  commands  control  BEAV's  access  to files.   Files
Xare loaded into buffers or are written from  buffers.    Commands
Xthat  prompt  for  a  file  name  also  accept  range parameters.
XRange parameters are always given in  the  numeric  base  of  the
Xcurrent  window.    Thus  if  you  are displaying data in decimal
Xformat then the range parameters must be entered in decimal.
X
X      The size of  a  file  read  or  write  can  be  limited  by
Xspecifying  a  range.    The range parameter specifies the offset
Xinto  the  file,  not  the  buffer.    Range  parameters  can  be
Xspecified in these forms;
X
X      <file name> <start address>
X
X      <file name> <start address> <end address>
X
X      <file name> <start address> +<length>
X
X      The first form causes the read or write to begin  from  the
X<start  address>  value  until  the end of the buffer on write or
Xthe end of the file on read.
X
X      The second  form  reads  or  writes  from  <start  address>
Xuntil <end address> non-inclusive.
X
X      The  third  form  reads  or writes from <start address> for
X<length> bytes.
X
X      Thus, if the command 'file-read' is  given  and  you  enter
Xat  the  prompt;    main.obj  1000 +100.   If the current display
Xmode is hex, the file "main.obj"  will  be  read  from  hex  byte
Xaddress 1000 to 10FF into the buffer.
X
X      Ctl-X Ctl-R    file-read                Sh-F2
X
X      Prompt  for  a  file  name  and  read  that  file  into the
Xcurrent buffer.   This overwrites the  current  contents  of  the
Xbuffer.    The  buffer  name  is  not changed but the buffer file
Xname is set to the new file name.
X
X      Ctl-X Ctl-S    file-save                Sh-F3
X
X      Write the current buffer out to the file  if  it  has  been
Xchanged.   If the buffer has not been changed then do nothing.
X
X 
X 
X 
X 
X 
X 
X
X
X                              - 17 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X      Ctl-X V        file-view
X
X      Prompt  for  a  file  name  and read file into a new buffer
Xand display in current window.   Set to read-only mode.
X
X      Ctl-X Ctl-V    file-visit               Sh-F4
X
X      Prompt for a file name.    If  the  buffer  already  exists
Xthen  display  it  in  the current window.   Otherwise, read file
Xinto a new buffer and display in current window.    If  there  is
Xno such file then create it.
X
X      Esc U          file-visit-split
X
X      Same  as  above  but  split  current window and display new
Xbuffer.   This displays  the  new  buffer  as  well  as  the  old
Xbuffer.
X
X      Ctl-X Ctl-W    file-write               Sh-F5
X
X      Prompt  for  a  file name, then write the current buffer to
Xthat file.
X
X      Ctl-X Tab      insert-file              Sh-F8
X
X      Prompt for a file  name  and  insert  that  file  into  the
Xcurrent buffer at the cursor position.
X
X      Ctl-X Return   save-all-buffers         Sh-F6
X
X      Write   all   buffers  that  have  been  changed  to  their
Xrespective files.
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 18 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X 3.5                 Window Management
X
X      BEAV presents information  to  the  user  in  one  or  more
Xwindows.    Each  window  is  a view into a buffer where the data
Xis actually stored.    The  window  controls  how  this  data  is
Xformatted  for  display  to  the user.   Data can be displayed as
XHEX bytes, OCTAL  bytes,  ASCII  characters,  plus  many  others.
XThe  display  format  is  associated with the window.   Thus if a
Xnew buffer is displayed in  the  current  window  that  new  data
Xwill be displayed in the current windows format.
X
X      The  only  limit  to  the  number  of windows is the screen
Xsize.   A window can be no smaller than two lines.    This  along
Xwith  the  mode  line associated with each window limits to eight
Xthe number of windows on an IBM PC 25 line screen.
X
X      Any window  can  view  any  buffer  including  having  many
Xwindows  on  the  same  buffer.    For  example,  two windows can
Xdisplay the same buffer but present the  data  in  two  different
Xmodes.    One  window could display HEX bytes and the other could
Xdisplay ASCII characters.
X
X      Ctl-P          change-window-back       Ctl-PageUp
X      Ctl-N          change-window-forw       Ctl-PageDown
X
X      These commands move the cursor  to  the  next  or  previous
Xwindow on the screen, making it the current window.
X
X      Ctl-X Z        window-enlarge
X      Ctl-X Ctl-Z    window-shrink
X
X      Enlarge or shrink the current window size by one line.
X
X      Esc !          window-reposition
X
X      Move  window  position  so  that  the cursor is centered in
Xthe window.   The cursor position in the buffer does not change.
X
X      Ctl-X 2        window-split
X
X      Split the current window into  equal  parts.    Both  haves
Xhave the same display mode and view the save buffer.
X
X      Ctl-X 1        window-single
X
X      Expand  the  current window to fill the entire display, all
Xother windows are removed.   Make the  current  window  the  only
Xwindow   displayed.    This  has  no  effect  on  the  underlying
Xbuffers except that they may not be displayed any more.
X
X 
X 
X 
X
X
X                              - 19 -
X
X
X 
X
X
END_OF_FILE
if test 32050 -ne `wc -c <'beav1.doc'`; then
    echo shar: \"'beav1.doc'\" unpacked with wrong size!
fi
# end of 'beav1.doc'
fi
echo shar: End of archive 8 \(of 10\).
cp /dev/null ark8isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
>>>>>>>>>>>>>>>> Peter Reilley ..... pvr@wang.com <<<<<<<<<<<<<<<<<<<<<<<
                     Well, that about says it.

pvr@wang.com (Peter Reilley) (06/06/91)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 9 (of 10)."
# Contents:  beav2.doc
# Wrapped by pvr@elf on Thu Mar 14 08:16:48 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'beav2.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'beav2.doc'\"
else
echo shar: Extracting \"'beav2.doc'\" \(35789 characters\)
sed "s/^X//" >'beav2.doc' <<'END_OF_FILE'
X
X                         BEAV User Manual
X
X
X 
X      Ctl-X 0        window-delete
X
X      Delete the current window and expand the  upper  window  to
Xfill  the  space.    This  has no effect on the underlying buffer
Xexcept that it may not be displayed any more.
X
X      Esc Ctl-A      display-ascii
X      Esc Ctl-E      display-ebcdic
X      Esc Ctl-H      display-hex
X      Esc Ctl-O      display-octal
X      Esc Ctl-D      display-decimal
X      Esc Ctl-B      display-binary
X
X      These  commands  set  the  window  display   mode.     Text
Xbuffers   can   be  displayed  as  ASCII  or  EBCDIC  characters.
XBuffers that are not human readable  can  also  be  displayed  in
Xhexadecimal, octal, decimal, or binary format.
X
X      Esc 1          display-bytes
X      Esc 2          display-words
X      Esc 4          display-double-words
X
X      As  a  further  option  on the non-text display modes, data
Xcan be displayed as 8, 16, or 32 bit values.
X
X      Ctl-E          display-swap-order
X
X      When data is displayed as words or double words  the  order
Xof  significance  can  be changed.   In Intel microprocessors the
Xleast significant  byte  of  a  word  is  stored  at  the  lowest
Xaddress.    Thus  if  the  word  5892 (HEX) were stored at memory
Xaddress 10, then 92 (HEX) would be stored at address  10  and  58
X(HEX)   would   be   stored   at   address   11.     In  Motorola
Xmicroprocessors the reverse is true.
X      This  command  toggles  between  the  Intel  and   Motorola
Xschemes  of  assembling bytes into words and double words.   This
Xcommand has no effect on byte display  or  on  the  text  display
Xmodes.   The data in the buffer is not changed.
X
X      Ctl-A          display-byte-shift
X
X      This  command  changes the offset from the beginning of the
Xbuffer used to assemble words and  double  words.    The  default
Xshift  is  0.    For example, a double word at address 10 is made
Xup of the bytes at address 10, 11, 12, and  13.    With  a  shift
Xof  1  that  double  word  would be made of bytes 11, 12, 13, and
X14.   With a shift of 2 then bytes 12, 13, 14, and  15  would  be
Xused.    The  maximum  shift  in word display mode is one and the
Xmaximum shift in double word mode is three.
X
X 
X 
X 
X
X
X                              - 20 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X      The buffer is in effect shifted  toward  the  beginning  of
Xthe  buffer  with  1, 2, or 3 bytes becoming not visible.   These
Xbytes are not lost, they become visible when  the  shift  is  set
Xto  zero.    This  command  cycles  through  all  possible  shift
Xvalues.    There  is  no  effect  in any byte display mode or any
Xtext display mode.
X
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 21 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X 3.6                 Inserting and deleting
X
X      These commands are  the  core  of  BEAV.    These  commands
Xallow  the  buffer  to  be  edited in a similar fashion to a text
Xeditor.   BEAV has an insert mode much the same as  text  editors
Xbut  it  only  works  when  displaying  data  in  one of the text
Xmodes, either ASCII or EBCDIC.   In other modes it  doesn't  make
Xany  sense  to  insert characters as they are typed when there is
Xmore than one characters per unit.   In the data modes  there  is
Xa  command  that  inserts  a  unit  of  zeros  into  the  buffer.
XSimilarly  the  delete  commands always delete a unit rather than
Xa character.   In a text mode the delete commands work  as  in  a
Xtext editor because a unit is a character.
X
X      Ctl-X I        insert-unit
X
X      Insert  a  zero  at  the cursor position.   The rest of the
Xdata moves down one place.   Thus,  if  double  words  are  being
Xdisplayed,   four   bytes   are   inserted   before   the  cursor
Xposition.   These bytes are initialized to zero.    This  command
Xworks in all display modes.
X
X      Ctl-X Ctl-A    insert-toggle            Insert
X
X      In  either  of  the  two  text  modes  this command toggles
Xbetween insert mode and overwrite mode.    In  insert  mode  each
Xcharacter  that  is  typed is inserted in front of the cursor and
Xthe rest of the buffer is moved down.    In  overwrite  mode  the
Xtyped  characters  replace  the  character that is at the cursor.
XThis command has no effect in a non-text display mode.
X
X      Ctl-Q          insert-literally         Esc Q
X
X      This command sets a special temporary mode where  the  next
Xtyped  character  is  inserted  in  the buffer no matter what the
Xcharacter is.   This allows control codes to be inserted  in  the
Xbuffer  when  in  a  text  display mode.   Alternatively the same
Xbyte could be inserted into the buffer by using one of  the  data
Xdisplay  modes.    It might be faster to use this command on some
Xoccasions.
X
X      Ctl-T          unit-twiddle
X
X      The unit at the cursor is swapped with the previous unit.
X
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 22 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X      Rubout         delete-back-char         Backspace
X
X      This command deletes the character before  the  cursor  and
Xpulls  the  rest  of the buffer back.   The cursor remains on the
Xsame character as it moves back.   It  only  works  in  the  text
Xand byte display modes.
X
X      Ctl-D          delete-forw-char         Delete
X
X      The  character  at  the cursor is deleted and the buffer is
Xpulled back.   The cursor remains  at  the  same  position.    It
Xonly works in the text and byte display modes.
X
X      Esc Rubout     delete-back-unit         Esc Ctl-K
X
X      This  command  deletes the unit before the cursor and pulls
Xthe rest of the buffer back.   The cursor  remains  on  the  same
Xunit as it moves back.
X
X      Esc D          delete-forw-unit
X
X      The  unit  at  the  cursor  is  deleted  and  the buffer is
Xpulled back.   The cursor remains at the same position.
X
X      Esc W          copy-mark-to-cursor      F7
X
X      The area in  the  buffer  from  the  mark  to  the  current
Xcursor  position  is  copied  into the kill buffer.   If the mark
Xis not set before this command is given an error is reported.
X
X      Ctl-W          delete-mark-to-cursor    F8
X
X      The area in  the  buffer  from  the  mark  to  the  current
Xcursor  position  is  deleted  and  placed  into the kill buffer.
XIf the mark is not set before this command is given an  error  is
Xreported.
X
X      Ctl-Y          yank                     F6
X
X      The  contents  of  the  kill  buffer  is  inserted into the
Xbuffer at the cursor position.   The kill buffer  itself  is  not
Xchanged.
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 23 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X 3.7  Search and Replace Commands
X
X      BEAV  has  very powerful search and replace commands.   The
Xsearch and replace string can be entered in any  of  the  display
Xmodes.    The  search  and  replace strings can each be up to 256
Xbytes long.   The display mode can be changed at any  time  while
Xentering  the  string.   Wild cards can be placed down to the bit
Xlevel on both the search and replace  strings.    The  wild  card
Xcharacter, '?', will match any value that it is compared with.
X
X      When  a  wild  card  is  placed  in  the  replace string it
Xleaves the destination data unchanged at that  position.    Thus,
Xif  the  destination  contains the ASCII string '41 42 43 44' and
Xthe replace string contains '66 67 ?? 69'  the  result  would  be
X'66 67 43 69'.
X
X      Wild  cards  can  be  placed  in  any  position  that makes
Xsense.   If you want to use wild cards in an  ASCII  string  then
Xyou  must  switch  to  another mode to enter them.   You can then
Xswitch back to ASCII mode.   In this case a '?'  will  appear  in
Xthe  position  where the wild card has been placed but it appears
Xexactly the same as a standard question mark.   In  fact  if  you
Xtype  a  '?'  over  the  wild  card  there  will  be  no apparent
Xchange.   However, the character will no longer be  a  wild  card
Xbut  a  standard  question mark.   To see the true wild cards you
Xmust use a data display mode.   In fact  if  the  wild  card  has
Xbeen  set  on  the  bit  level then you must go to binary display
Xmode to see its actual position.
X
X      The commands to change  the  display  mode  in  search  and
Xreplace  are  the  same  as  for  the  window display mode.   The
Xsearch and replace strings can be  scrolled  back  an  forth  and
Xthe  cursor  moved  using  the  same  commands as for the window.
XWhile performing a replace command you  can  switch  between  the
Xsearch  string  and  replace string by using the 'move-back-page'
Xor 'move-forw-page' commands.
X
X      Esc S          search-forw              F3
X
X      Prompts  for  a  search  string  then  searches  from   the
Xcurrent  cursor  position  for  the  first match.   The cursor is
Xpositioned at the first unit of the match.
X
X      Esc R          search-back
X
X      This command is the same as the previous  one  except  that
Xit searches backward.
X
X 
X 
X 
X 
X 
X
X
X                              - 24 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X      Esc T          search-again             F4
X
X      This  command  repeats the previous search command, forward
Xor backward.    The  cursor  is  first  moved  one  byte  in  the
Xappropriate direction before the search is repeated.
X
X      Esc %          replace                  F5
X
X      Prompt  for  search  string.    After  entering  the search
Xstring hit return and  you  will  be  prompted  for  the  replace
Xstring.    After  entering  the replace string hit return.   BEAV
Xwill then search for the first  match  with  the  search  string.
XIf  a  match  is  found  you  will  be  prompted with '(R)eplace,
X(S)kip, (A)ll, (O)ne, (Q)uit'
X
X      If you type  a  'R'  the  replace  will  be  done  at  this
Xlocation  and  the  search will continue.   If you type a 'S' the
Xreplace will not be done  and  search  will  continue.    If  you
Xtype  an  'A'  the  replace  will be done and will be done at all
Xfuture matches without pausing for conformation.    If  you  type
Xan  'O'  the replace will be done at this location and the search
Xwill  stop.    If  you  type  a  'Q'  then  the  search  will  be
Xterminated.
X
X      Ctl-R          recall-srch-string
X
X      If you enter search  or  replace  previously  used  strings
Xcan be recalled with this command.
X
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 25 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X 3.8  Exiting BEAV
X
X      While  using  BEAV  individual buffers may be saved to disk
Xduring the editing session.   When quitting BEAV  you  must  save
Xall  buffers  or  delete  all  buffers.    There are two commands
Xthat that do this.
X
X      Ctl-C          quit-no-save             Sh-F10
X
X      If there are any unsaved buffers you will be  prompted  for
Xconformation  before  proceeding.    All  buffers will be deleted
Xthen you will exit.
X
X      Ctl-X Ctl-E    quit-save-all            Sh-F9
X
X      All buffers are saved before exiting.
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 26 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X 3.9  Printing
X
X      The data that is being displayed in  BEAV  can  be  printed
Xor  sent  to  a  file  in  the same format as displayed.   If the
Xcurrent window is displaying octal words and a print  command  is
Xgiven  the  format  of  the  print  will  be in the format of the
Xwindow; that is, octal words.
X
X      Esc P          print-mark-to-cursor     Ctl-Print
X
X      To use this command you must set the mark  and  the  cursor
Xto  define  the  region  that  you want printed.   If the mark is
Xnot set it as assumed to be at the  first  unit.    The  position
Xof  the  mark  and  cursor  are  rounded  to  include  the entire
Xspecified  line  unlike  the   other   mark-to-cursor   commands.
XAfter  you  enter  the  command  you will be prompted with 'Print
Xto:'.   You can enter a file name or a device name  to  send  the
Xprint  image  to.    If you enter 'PRN' most systems will print a
Xhard copy.
X
X      This is useful for getting a print out of the  current  key
Xbindings.    To  do  this  give  the 'help' command 'F1'.   Go to
Xthe bottom of the help window  using  the  'move-to-end'  command
X'End',  the  mark  will  be assumed to be at the beginning of the
Xbuffer.    Issue  the  'print-mark-to-cursor'  command.     Enter
X'PRN'  at  the  prompt.    This  should  print  the complete help
Xbuffer and will reflect any changes that you  have  made  to  the
Xkey bindings.
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 27 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X 3.10 Keyboard Macros
X
X      BEAV  has  the  capability of recording key strokes as they
Xare entered and playing them back later.    This  is  useful  for
Xrepeating multi-keystroke operations.
X
X      Ctl-X (        macro-start
X
X      Start  recording  key  strokes.   There is no effect on the
Xoperation  of  the  key  strokes.    Any  previous  recorded  key
Xstrokes are cleared.
X
X      Ctl-X )        macro-end
X
X      Stop  recording  key  strokes.    The   key   strokes   are
Xavailable for play back.
X
X      Ctl-X E        macro-execute
X
X      Play  back  the  recorded  key  strokes.    The key strokes
Xthat were recorded are played back as if they were typed  at  the
Xkeyboard.
X
X
X 3.11 Key Binding
X
X      BEAV   provides   a   user  configurable  interface.    The
Xinterface  is  controlled  by  a  set  of  key  bindings.    This
Xrelates the command that will be executed when a  particular  key
Xstroke  is  entered.   There are a set of default key bindings as
Xdescribed in this manual.    These  can  be  changed  to  reflect
Xyour  preferences.    When  a  change  is made it is reflected in
Xthe help screen.
X
X      Ctl-X ?        binding-for-key          Sh-F1
X
X      This command will tell you  what  function  a  certain  key
Xsequence  is  bound  to.   When this command is given you will be
Xprompted for a key stroke or key  stroke  sequence.    BEAV  will
Xreport back with the function name.
X
X      Esc K          bind-to-key
X
X      First  you  will  prompted for a function name.   Enter the
Xname of the function that  you  wish  to  create  a  new  binding
Xfor.    Function  names  are the names listed in this manual that
Xare of the form of  'move-forw-unit'  or  'display-hex'.    After
Xyou  enter  the  name  hit  return.    You will be prompted for a
Xkey.   This can be in the form of a single standard key  such  as
X'Z'.   Standard key sequences can be entered such as 'Ctl-X Z' 
X 
X 
X 
X
X
X                              - 28 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
Xor   'Esc  Z'.    Special  keys  can  be  entered  such  as  'F1'
X(function key 1) or 'Page Down'.   It is  probably  a  good  idea
Xto  not  use keys that are needed for editing.   If you bound 'Z'
Xto a function then you would  not  be  able  to  enter  it  as  a
Xkeystroke  when  using  ASCII  display  mode.    You  could still
Xenter it using the 'insert-literally'  command  or  doing  it  in
Xone of the data display modes but this would be more cumbersome.
X
X      Ctl-X L        bindings-load
X
X      You  are  prompted  for  a  file name that contains the key
Xbinding that you wish to set.   This file  is  read  in  and  the
Xappropriate  bindings  are  set.    The  text in the binding file
Xshould be of the form;
X
X<key name>            <function name>    <key code>
X
X      For example;
X
XCtl-X Ctl-P           move-back-char     0550
XF1                    move-forw-char     04bb
XCtl-A                 move-forw-unit     0141
XEsc Ctl-T             move-back-unit     0354
X
X      The easiest way of producing a valid key  binding  file  is
Xto  set  the  desired  bindings  in BEAV.   Next issue the 'help'
Xcommand (ESC ?), then write the buffer out  with  the  file-write
Xcommand  (Ctl-X  Ctl-W).    The  file  created  will  be  a valid
Xformat for loading and can be edited  as  desired.    It  is  the
Xonly way to reliably get the <key code> number.
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 29 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X 3.12 Special Functions
X
X      These  are  the  commands  that  do not logically fit under
Xone of the previous headings
X
X      Ctl-G          abort-cmd                F10
X
X      This command aborts the  current  command.    It  can  even
Xabort  a  partially entered command.   Thus, if you have typed an
X'Esc' as that start of a command you can  type  Ctl-G  to  return
Xto the normal command entry mode.
X
X      Esc A          auto-save
X
X      BEAV  can  be  set to automatically save the current buffer
Xafter  a  specified  number  of  buffer  editing   commands   are
Xgiven.     This   command   first   prompts  for  the  number  of
Xoperations before the save is made.   If a  zero  is  entered  at
Xthe  prompt,  this  feature  is disabled.   The default condition
Xof this command is disabled.
X
X      Esc C          compare
X
X      This is a powerful feature of BEAV.   The contents  of  two
Xwindows  are  compared  byte  for  byte  from  the current cursor
Xposition in each window.   There must be exactly two  windows  to
Xuse  this  command.   These windows can be displaying the same or
Xdifferent buffers.   When a difference is  found  the  cursor  in
Xeach  window  is  moved  to  that  position  and both windows are
Xmoved  accordingly.    The  display  mode  does  not  affect  the
Xoperation of  this  command  except  in  restricting  the  cursor
Xposition to whole units.
X
X      Esc X          extended-command
X
X      If  any  command loses its binding, this command allows the
Xunbound command to be used.   A  command  can  lose  its  binding
Xbecause  the  binding  was  assigned  to  another command.   When
Xthis command  is  given  you  will  be  prompted  for  a  command
Xname.    Enter  the  command  name  that  you wish to execute, it
Xwill be executed as if you had typed its key binding.
X
X      Ctl-L          refresh-screen
X
X      The  screen  is  reprinted  from  BEAV's  internal  buffer.
XThis is useful if the display is messed up  due  to  transmission
Xerrors.   On a PC this is unlikely to happen.
X
X 
X 
X 
X 
X 
X
X
X                              - 30 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X      Esc Ctl-V      show-version
X
X      The  version  and  date of BEAV is displayed in the command
Xline.
X
X      Ctl-X C        spawn-shell
X
X      A new shell  is  created.    You  can  return  to  BEAV  by
Xtyping 'exit'.
X
X      Ctl-U          repeat count
X
X      This  command  prompts  for  a number to be entered.   This
Xcauses the next command given to be repeated by  that  number  of
Xtimes.    This  command  cannot  have  it's  binding  changed and
Xcannot be issued using the 'extended-command' function.
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 31 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X4.    Alphabetical list of commands by name
X
Xabort-cmd                      Ctl-G             3.12
Xabort-cmd                      Ctl-X,Ctl-G       3.12
Xabort-cmd                      Esc,Ctl-G         3.12
Xabort-cmd                      F10               3.12
Xauto-save                      Esc,A             3.12
Xbind-to-key                    Esc,K             3.11
Xbinding-for-key                Ctl-X,?           3.11
Xbinding-for-key                Sh-F1             3.11
Xbindings-load                  Ctl-X,L           3.11
Xbuffer-set-file-name           Ctl-F7            3.3
Xbuffer-set-file-name           Ctl-X,Ctl-F       3.3
Xbuffer-set-file-name           Sh-F7             3.3
Xbuffer-set-name                Esc,Ctl-N         3.3
Xbuffer-size-lock               Ctl-X,Ctl-L       3.3
Xbuffers-display                Ctl-F1            3.3
Xbuffers-display                Ctl-X,Ctl-B       3.3
Xchange-buffer                  Ctl-F2            3.3
Xchange-buffer                  Ctl-X,B           3.3
Xchange-to-next-buffer          Ctl-F4            3.3
Xchange-to-next-buffer          Esc,+             3.3
Xchange-to-prev-buffer          Ctl-F5            3.3
Xchange-to-prev-buffer          Esc,-             3.3
Xchange-window-back             Ctl-PageUp        3.5
Xchange-window-back             Ctl-X,P           3.5
Xchange-window-forw             Ctl-PageDown      3.5
Xchange-window-forw             Ctl-X,N           3.5
Xcompare                        Esc,C             3.12
Xcopy-mark-to-cursor            Esc,W             3.6
Xcopy-mark-to-cursor            F7                3.6
Xdelete-back-char               Backspace         3.6
Xdelete-back-char               Rubout            3.6
Xdelete-back-unit               Esc,Ctl-K         3.6
Xdelete-back-unit               Esc,Rubout        3.6
Xdelete-forw-char               Ctl-D             3.6
Xdelete-forw-char               Delete            3.6
Xdelete-forw-unit               Esc,D             3.6
Xdelete-mark-to-cursor          Ctl-W             3.6
Xdelete-mark-to-cursor          F8                3.6
Xdisplay-ascii                  Esc,Ctl-A         3.5
Xdisplay-binary                 Esc,Ctl-B         3.5
Xdisplay-byte-shift             Ctl-A             3.5
Xdisplay-bytes                  Esc,1             3.5
Xdisplay-decimal                Esc,Ctl-D         3.5
Xdisplay-double-words           Esc,4             3.5
Xdisplay-ebcdic                 Esc,Ctl-E         3.5
Xdisplay-hex                    Esc,Backspace     3.5
Xdisplay-octal                  Esc,Ctl-O         3.5
Xdisplay-swap-order             Ctl-E             3.5
X 
X 
X 
X
X
X                              - 32 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
Xdisplay-words                  Esc,2             3.5
Xextended-command               Esc,X             3.12
Xfile-read                      Ctl-X,Ctl-R       3.4
Xfile-read                      Sh-F2             3.4
Xfile-save                      Ctl-X,Ctl-S       3.4
Xfile-save                      Sh-F3             3.4
Xfile-view                      Ctl-X,V           3.4
Xfile-visit                     Ctl-X,Ctl-V       3.4
Xfile-visit                     Sh-F4             3.4
Xfile-visit-split               Esc,U             3.4
Xfile-write                     Ctl-X,Ctl-W       3.4
Xfile-write                     Sh-F5             3.4
Xhelp                           Esc,?             3.1
Xhelp                           F1                3.1
Xinsert-file                    Ctl-F8            3.4
Xinsert-file                    Ctl-X,Tab         3.4
Xinsert-file                    Sh-F8             3.4
Xinsert-literally               Ctl-Q             3.6
Xinsert-literally               Esc,Q             3.6
Xinsert-toggle                  Ctl-X,Ctl-A       3.6
Xinsert-toggle                  Insert            3.6
Xinsert-unit                    Ctl-X,I           3.6
Xkill-buffer                    Ctl-F3            3.3
Xkill-buffer                    Ctl-X,K           3.3
Xmacro-end                      Ctl-X,)           3.10
Xmacro-execute                  Ctl-X,E           3.10
Xmacro-start                    Ctl-X,(           3.10
Xmark-set                       Esc,.             3.2
Xmark-set                       F2                3.2
Xmove-back-char                 Ctl-B             3.2
Xmove-back-char                 West              3.2
Xmove-back-line                 Ctl-P             3.2
Xmove-back-line                 North             3.2
Xmove-back-page                 Esc,V             3.2
Xmove-back-page                 PageDown          3.2
Xmove-back-unit                 Ctl-West          3.2
Xmove-back-unit                 Esc,B             3.2
Xmove-forw-char                 Ctl-F             3.2
Xmove-forw-char                 East              3.2
Xmove-forw-line                 Ctl-N             3.2
Xmove-forw-line                 South             3.2
Xmove-forw-page                 Ctl-V             3.2
Xmove-forw-page                 PageUp            3.2
Xmove-forw-unit                 Ctl-East          3.2
Xmove-forw-unit                 Esc,F             3.2
Xmove-forw-unit                 Sh-Tab            3.2
Xmove-to-beginning              Esc,<             3.2
Xmove-to-beginning              Home              3.2
Xmove-to-buffer-split           Esc,G             3.2
Xmove-to-byte                   Ctl-X,G           3.2
X 
X 
X 
X
X
X                              - 33 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
Xmove-to-byte                   F9                3.2
Xmove-to-end                    End               3.2
Xmove-to-end                    Esc,>             3.2
Xmove-window-down               Ctl-X,Ctl-N       3.2
Xmove-window-down               Ctl-Z             3.2
Xmove-window-up                 Ctl-X,Ctl-P       3.2
Xmove-window-up                 Esc,Z             3.2
Xprint-mark-to-cursor           Ctl-Print         3.9
Xprint-mark-to-cursor           Esc,P             3.9
Xquit-no-save                   Ctl-C             3.8
Xquit-no-save                   Ctl-F10           3.8
Xquit-no-save                   Ctl-X,Ctl-C       3.8
Xquit-no-save                   Sh-F10            3.8
Xquit-save-all                  Ctl-F9            3.8
Xquit-save-all                  Ctl-X,Ctl-E       3.8
Xquit-save-all                  Sh-F9             3.8
Xrecall-srch-string             Ctl-R             3.7
Xrefresh-screen                 Ctl-L             3.12
Xreplace                        Esc,%             3.7
Xreplace                        F5                3.7
Xsave-all-buffers               Ctl-X,Return      3.4
Xsave-all-buffers               Sh-F6             3.4
Xsave-mark-to-cursor            Esc,O             3.3
Xsearch-again                   Esc,T             3.7
Xsearch-again                   F4                3.7
Xsearch-back                    Esc,R             3.7
Xsearch-forw                    Esc,S             3.7
Xsearch-forw                    F3                3.7
Xshow-position                  Ctl-X,=           3.2
Xshow-version                   Esc,Ctl-V         3.12
Xspawn-shell                    Ctl-X,C           3.12
Xswap-cursor-and-mark           Ctl-X,Ctl-X,      3.2
Xunit-twiddle                   Ctl-T             3.6
Xwindow-delete                  Ctl-X,0           3.5
Xwindow-enlarge                 Ctl-X,Z           3.5
Xwindow-link                    Esc,L             3.2
Xwindow-reposition              Esc,!             3.5
Xwindow-shrink                  Ctl-X,Ctl-Z       3.5
Xwindow-single                  Ctl-X,1           3.5
Xwindow-split                   Ctl-X,2           3.5
Xyank                           Ctl-Y             3.6
Xyank                           F6                3.6
Xyank-buffer                    Ctl-F6            3.3
Xyank-buffer                    Esc,Y             3.3
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 34 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X5.    Alphabetical list of commands by default key binding
X
Xdelete-back-char               Backspace         3.6
Xdisplay-byte-shift             Ctl-A             3.5
Xmove-back-char                 Ctl-B             3.2
Xquit-no-save                   Ctl-C             3.8
Xdelete-forw-char               Ctl-D             3.6
Xdisplay-swap-order             Ctl-E             3.5
Xmove-forw-unit                 Ctl-East          3.2
Xmove-forw-char                 Ctl-F             3.2
Xbuffers-display                Ctl-F1            3.3
Xquit-no-save                   Ctl-F10           3.8
Xchange-buffer                  Ctl-F2            3.3
Xkill-buffer                    Ctl-F3            3.3
Xchange-to-next-buffer          Ctl-F4            3.3
Xchange-to-prev-buffer          Ctl-F5            3.3
Xyank-buffer                    Ctl-F6            3.3
Xbuffer-set-file-name           Ctl-F7            3.3
Xinsert-file                    Ctl-F8            3.4
Xquit-save-all                  Ctl-F9            3.8
Xabort-cmd                      Ctl-G             3.12
Xrefresh-screen                 Ctl-L             3.12
Xmove-forw-line                 Ctl-N             3.2
Xmove-back-line                 Ctl-P             3.2
Xchange-window-forw             Ctl-PageDown      3.5
Xchange-window-back             Ctl-PageUp        3.5
Xprint-mark-to-cursor           Ctl-Print         3.9
Xinsert-literally               Ctl-Q             3.6
Xrecall-srch-string             Ctl-R             3.7
Xunit-twiddle                   Ctl-T             3.6
Xmove-forw-page                 Ctl-V             3.2
Xdelete-mark-to-cursor          Ctl-W             3.6
Xmove-back-unit                 Ctl-West          3.2
Xmacro-start                    Ctl-X,(           3.10
Xmacro-end                      Ctl-X,)           3.10
Xwindow-delete                  Ctl-X,0           3.5
Xwindow-single                  Ctl-X,1           3.5
Xwindow-split                   Ctl-X,2           3.5
Xshow-position                  Ctl-X,=           3.2
Xbinding-for-key                Ctl-X,?           3.11
Xchange-buffer                  Ctl-X,B           3.3
Xspawn-shell                    Ctl-X,C           3.12
Xinsert-toggle                  Ctl-X,Ctl-A       3.6
Xbuffers-display                Ctl-X,Ctl-B       3.3
Xquit-no-save                   Ctl-X,Ctl-C       3.8
Xquit-save-all                  Ctl-X,Ctl-E       3.8
Xbuffer-set-file-name           Ctl-X,Ctl-F       3.3
Xabort-cmd                      Ctl-X,Ctl-G       3.12
Xbuffer-size-lock               Ctl-X,Ctl-L       3.3
Xmove-window-down               Ctl-X,Ctl-N       3.2
X 
X 
X 
X
X
X                              - 35 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
Xmove-window-up                 Ctl-X,Ctl-P       3.2
Xfile-read                      Ctl-X,Ctl-R       3.4
Xfile-save                      Ctl-X,Ctl-S       3.4
Xfile-visit                     Ctl-X,Ctl-V       3.4
Xfile-write                     Ctl-X,Ctl-W       3.4
Xswap-cursor-and-mark           Ctl-X,Ctl-X,      3.2
Xwindow-shrink                  Ctl-X,Ctl-Z       3.5
Xmacro-execute                  Ctl-X,E           3.10
Xmove-to-byte                   Ctl-X,G           3.2
Xinsert-unit                    Ctl-X,I           3.6
Xkill-buffer                    Ctl-X,K           3.3
Xbindings-load                  Ctl-X,L           3.11
Xchange-window-forw             Ctl-X,N           3.5
Xchange-window-back             Ctl-X,P           3.5
Xsave-all-buffers               Ctl-X,Return      3.4
Xinsert-file                    Ctl-X,Tab         3.4
Xfile-view                      Ctl-X,V           3.4
Xwindow-enlarge                 Ctl-X,Z           3.5
Xyank                           Ctl-Y             3.6
Xmove-window-down               Ctl-Z             3.2
Xdelete-forw-char               Delete            3.6
Xmove-forw-char                 East              3.2
Xmove-to-end                    End               3.2
Xwindow-reposition              Esc,!             3.5
Xreplace                        Esc,%             3.7
Xchange-to-next-buffer          Esc,+             3.3
Xchange-to-prev-buffer          Esc,-             3.3
Xmark-set                       Esc,.             3.2
Xdisplay-bytes                  Esc,1             3.5
Xdisplay-words                  Esc,2             3.5
Xdisplay-double-words           Esc,4             3.5
Xmove-to-beginning              Esc,<             3.2
Xmove-to-end                    Esc,>             3.2
Xhelp                           Esc,?             3.1
Xauto-save                      Esc,A             3.12
Xmove-back-unit                 Esc,B             3.2
Xdisplay-hex                    Esc,Backspace     3.5
XCompare                        Esc,C             3.12
Xdisplay-ascii                  Esc,Ctl-A         3.5
Xdisplay-binary                 Esc,Ctl-B         3.5
Xdisplay-decimal                Esc,Ctl-D         3.5
Xdisplay-ebcdic                 Esc,Ctl-E         3.5
Xabort-cmd                      Esc,Ctl-G         3.12
Xdelete-back-unit               Esc,Ctl-K         3.6
Xbuffer-set-name                Esc,Ctl-N         3.3
Xdisplay-octal                  Esc,Ctl-O         3.5
Xshow-version                   Esc,Ctl-V         3.12
Xdelete-forw-unit               Esc,D             3.6
Xmove-forw-unit                 Esc,F             3.2
Xmove-to-buffer-split           Esc,G             3.2
X 
X 
X 
X
X
X                              - 36 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
Xbind-to-key                    Esc,K             3.11
Xwindow-link                    Esc,L             3.2
Xsave-mark-to-cursor            Esc,O             3.3
Xprint-mark-to-cursor           Esc,P             3.9
Xinsert-literally               Esc,Q             3.6
Xsearch-back                    Esc,R             3.7
Xdelete-back-unit               Esc,Rubout        3.6
Xsearch-forw                    Esc,S             3.7
Xsearch-again                   Esc,T             3.7
Xfile-visit-split               Esc,U             3.4
Xmove-back-page                 Esc,V             3.2
Xcopy-mark-to-cursor            Esc,W             3.6
Xextended-command               Esc,X             3.12
Xyank-buffer                    Esc,Y             3.3
Xmove-window-up                 Esc,Z             3.2
Xhelp                           F1                3.1
Xabort-cmd                      F10               3.12
Xmark-set                       F2                3.2
Xsearch-forw                    F3                3.7
Xsearch-again                   F4                3.7
Xreplace                        F5                3.7
Xyank                           F6                3.6
Xcopy-mark-to-cursor            F7                3.6
Xdelete-mark-to-cursor          F8                3.6
Xmove-to-byte                   F9                3.2
Xmove-to-beginning              Home              3.2
Xinsert-toggle                  Insert            3.6
Xmove-back-line                 North             3.2
Xmove-back-page                 PageDown          3.2
Xmove-forw-page                 PageUp            3.2
Xdelete-back-char               Rubout            3.6
Xbinding-for-key                Sh-F1             3.11
Xquit-no-save                   Sh-F10            3.8
Xfile-read                      Sh-F2             3.4
Xfile-save                      Sh-F3             3.4
Xfile-visit                     Sh-F4             3.4
Xfile-write                     Sh-F5             3.4
Xsave-all-buffers               Sh-F6             3.4
Xbuffer-set-file-name           Sh-F7             3.3
Xinsert-file                    Sh-F8             3.4
Xquit-save-all                  Sh-F9             3.8
Xmove-forw-unit                 Sh-Tab            3.2
Xmove-forw-line                 South             3.2
Xmove-back-char                 West              3.2
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 37 -
X
X
X 
X
X
X                         BEAV User Manual
X
X
X 
X6.    Release notes
X
X
X      Version 1.20  (3/10/91)  of  beav  contains  the  following
Xfixes and enhancements;
X
X*           Under   unix   files   are  created  with  read/write
X      permissions.
X
X*           Fixed the  bug  in  the  terminal  I/O  routine  that
X      caused  beav  to  spin  rather  than  give  up control when
X      waiting for a character.
X
X*           Added the ANSI #define that was missing for MSDOS.
X
X*           Changed the D16 #define to a unsigned short.
X
X*           Called ttclose on error exit.
X
X*           Check and limit ncol and nrow to  the  actual  screen
X      array size.
X
X*           Add  the  ability  to  load  key bindings from a file
X      automatically under MSDOS and unix.
X
X*           Add delete current window command.
X
X*           Support VT100 type function keys.
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X 
X
X
X                              - 38 -
X
X
X 
END_OF_FILE
if test 35789 -ne `wc -c <'beav2.doc'`; then
    echo shar: \"'beav2.doc'\" unpacked with wrong size!
fi
# end of 'beav2.doc'
fi
echo shar: End of archive 9 \(of 10\).
cp /dev/null ark9isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

-- 
>>>>>>>>>>>>>>>> Peter Reilley ..... pvr@wang.com <<<<<<<<<<<<<<<<<<<<<<<
                     Well, that about says it.

pvr@wang.com (Peter Reilley) (06/06/91)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 10 (of 10)."
# Contents:  display.c
# Wrapped by pvr@elf on Thu Mar 14 08:16:48 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'display.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'display.c'\"
else
echo shar: Extracting \"'display.c'\" \(49122 characters\)
sed "s/^X//" >'display.c' <<'END_OF_FILE'
X/*
X* The functions in this file handle redisplay. The
X* redisplay system knows almost nothing about the editing
X* process; the editing functions do, however, set some
X* hints to eliminate a lot of the grinding. There is more
X* that can be done; the "vtputc" interface is a real
X* pig. Two conditional compilation flags; the GOSLING
X* flag enables dynamic programming redisplay, using the
X* algorithm published by Jim Gosling in SIGOA. The MEMMAP
X* changes things around for memory mapped video. With
X* both off, the terminal is a VT52.
X*/
X
X#define LINT_ARGS   1           /* enable lint type checking */
X#include    "def.h"
X
XD32 get_long ();
XD16 get_int ();
Xvoid writ_echo ();
Xvoid uline ();
Xvoid ucopy ();
Xvoid modeline ();
Xvoid bin_to_text ();
Xuint fill_buf ();
Xuint get_currow ();
Xuint get_curcol ();
X#if MSDOS
Xvoid    mem_line ();
X#endif
X
X    extern    char    MSG_prn_to[];
X    extern    char    MSG_disp_r_n[];
X    extern    char    MSG_11lX[];
X    extern    char    MSG_11lo[];
X    extern    char    MSG_11ld[];
X    extern    char    MSG_03o[];
X    extern    char    MSG_06o[];
X    extern    char    MSG_011lo[];
X    extern    char    MSG_03u[];
X    extern    char    MSG_05u[];
X    extern    char    MSG_010lu[];
X    extern    char    MSG_02X[];
X    extern    char    MSG_04X[];
X    extern    char    MSG_08lX[];
X    extern    char    MSG_prog_name[];
X    extern    char    MSG_disp_b_lst[];
X    extern    char    MSG_file[];
X    extern    char    MSG_RO[];
X    extern    char    MSG_WL[];
X    extern    char    MSG_RW[];
X    extern    char    MSG_AU[];
X    extern    char    MSG_NOT_AU[];
X    extern    char    MSG_curs_asc[];
X    extern    char    MSG_curs_ebc[];
X    extern    char    MSG_curs_hex[];
X    extern    char    MSG_curs_bin[];
X    extern    char    MSG_curs_dec[];
X    extern    char    MSG_curs_oct[];
X    extern    char    MSG_siz_8[];
X    extern    char    MSG_siz_16[];
X    extern    char    MSG_siz_32[];
X    extern    char    MSG_siz_null[];
X    extern    char    MSG_int_shift[];
X    extern    char    MSG_mot_shift[];
X    extern    char    MSG_print1[];
X    extern    char    MSG_print2[];
X#if RUNCHK
X    extern    char    ERR_disp_1[];
X    extern    char    ERR_disp_2[];
X    extern    char    ERR_disp_3[];
X    extern    char    ERR_disp_4[];
X    extern    char    ERR_disp_5[];
X    extern    char    ERR_disp_6[];
X#endif
X
X#include    "lintfunc.dec"
Xextern char ebcdic_table[];
X
Xextern  bool    mem_map;
X
X/*
X* You can change these back to the types
X* implied by the name if you get tight for space. If you
X* make both of them "int" you get better code on the VAX.
X* They do nothing if this is not Gosling redisplay, except
X* for change the size of a structure that isn't used.
X* A bit of a cheat.
X*/
X#define XCHAR   int
X#define XSHORT  int
X
X/*
X* A video structure always holds
X* an array of characters whose length is equal to
X* the longest line possible. Only some of this is
X* used if "ncol" isn't the same as "NCOL".
X*/
Xtypedef struct vid
X{
X    short   v_hash;             /* Hash code, for compares.     */
X    short   v_flag;             /* Flag word.                   */
X    short   v_color;            /* Color of the line.           */
X            XSHORT v_cost;      /* Cost of display.     */
X    char    v_text[NCOL];       /* The actual characters.       */
X}                   VIDEO;
X
X#define VFCHG   0x0001          /* Changed.                     */
X#define VFHBAD  0x0002          /* Hash and cost are bad.       */
X
X/*
X* SCORE structures hold the optimal
X* trace trajectory, and the cost of redisplay, when
X* the dynamic programming redisplay code is used.
X* If no fancy redisplay, this isn't used. The trace index
X* fields can be "char", and the score a "short", but
X* this makes the code worse on the VAX.
X*/
Xtypedef struct
X{
X    XCHAR s_itrace;             /* "i" index for track back.    */
X    XCHAR s_jtrace;             /* "j" index for trace back.    */
X    XSHORT s_cost;              /* Display cost.                */
X}               SCORE;
X
Xint     sgarbf = TRUE;          /* TRUE if screen is garbage.   */
Xint     vtrow = 0;              /* Virtual cursor row.          */
Xint     vtcol = 0;              /* Virtual cursor column.       */
Xint     tthue = CNONE;          /* Current color.               */
Xint     ttrow = HUGE;           /* Physical cursor row.         */
Xint     ttcol = HUGE;           /* Physical cursor column.      */
Xint     tttop = HUGE;           /* Top of scroll region.        */
Xint     ttbot = HUGE;           /* Bottom of scroll region.     */
Xchar    file_off_bad = FALSE;   /* Have file offsets been changed */
X
XVIDEO * vscreen[NROW];          /* Edge vector, virtual.        */
XVIDEO * pscreen[NROW];          /* Edge vector, physical.       */
XVIDEO video[2 * (NROW)];        /* Actual screen data.          */
XVIDEO blanks;                   /* Blank line image.            */
X
X#if     GOSLING
X/*
X* This matrix is written as an array because
X* we do funny things in the "setscores" routine, which
X* is very compute intensive, to make the subscripts go away.
X* It would be "SCORE   score[NROW][NROW]" in old speak.
X* Look at "setscores" to understand what is up.
X*/
XSCORE score[NROW * NROW];
X#endif
X
X/*
X* Initialize the data structures used
X* by the display code. The edge vectors used
X* to access the screens are set up. The operating
X* system's terminal I/O channel is set up. Fill the
X* "blanks" array with ASCII blanks. The rest is done
X* at compile time. The original window is marked
X* as needing full update, and the physical screen
X* is marked as garbage, so all the right stuff happens
X* on the first call to redisplay.
X*/
Xvoid vtinit ()
X{
X    register    VIDEO * vp;
X    register int    i;
X
X    ttopen ();
X    ttinit ();
X    vp = &video[0];
X    for (i = 0; i < NROW; ++i)
X        {
X        vscreen[i] = vp;
X        ++vp;
X        pscreen[i] = vp;
X        ++vp;
X        }
X    blanks.v_color = CTEXT;
X    for (i = 0; i < NCOL; ++i)
X        blanks.v_text[i] = ' ';
X}
X
X/*
X* Tidy up the virtual display system
X* in anticipation of a return back to the host
X* operating system. Right now all we do is position
X* the cursor to the last line, erase the line, and
X* close the terminal channel.
X*/
Xvoid vttidy ()
X{
X    ttcolor (CTEXT);
X    ttnowindow ();              /* No scroll window.    */
X    ttmove (nrow - 1, 0);       /* Echo line.           */
X    tteeol ();
X    tttidy ();
X    ttflush ();
X    ttclose ();
X}
X
X/*
X* Move the virtual cursor to an origin
X* 0 spot on the virtual display screen. I could
X* store the column as a character pointer to the spot
X* on the line, which would make "vtputc" a little bit
X* more efficient. No checking for errors.
X*/
Xvoid vtmove (row, col)
X{
X    vtrow = row;
X    vtcol = col;
X}
X
X/*
X* Write a character to the virtual display,
X* dealing with long lines and the display of unprintable
X* things like control characters. Also expand tabs every 8
X* columns. This code only puts printing characters into
X* the virtual display image. Special care must be taken when
X* expanding tabs. On a screen whose width is not a multiple
X* of 8, it is possible for the virtual cursor to hit the
X* right margin before the next tab stop is reached. This
X* makes the tab code loop if you are not careful.
X* Three guesses how we found this.
X*/
Xvoid vtputc (c)
Xregister int    c;
X{
X    register    VIDEO * vp;
X
X    vp = vscreen[vtrow];
X    if (vtcol >= ncol)
X        vp -> v_text[ncol - 1] = '$';
X    else
X        if (ISCTRL (c) != FALSE)
X            {
X            vtputc ('^');
X            vtputc (c ^ 0x40);
X            }
X        else
X            {
X            vp -> v_text[vtcol] = c;
X            vtcol++;
X            }
X
X}
X/*
X* Write an entire screen line in the correct format.    pvr
X*
X* This code only puts printing characters into
X* the virtual display image.
X* Return TRUE if something was printed to the line.
X*/
X#define REGI  register
Xbool vtputd (wp, row)
XWINDOW * wp;
Xint     row;                    /* line # to print to v screen */
X
X{
X    REGI VIDEO * vp;
X    REGI char  *lin_ptr,
X                ch,
X                mode;
X    REGI A32    row_offst;
X    REGI uint   chrs_per_row,
X                lin_offset,
X                crs,
X                i,
X                j,
X                k,
X                chrs_in_lin;
X    LINE * cur_line;
X    REGI uchar  tempc;
X    REGI D32 temp_long;
X    REGI D16 temp_int;
X    static char w_buf[128];      /* temp buffer for data */
X    REGI char  *fmnt_ptr;       /* pointer to format structure   */
X
X    vp = vscreen[vtrow];        /* point to VIDEO structure to print into */
X    mode = R_TYPE(wp);          /* get type of format structure */
X
X /* get number of bytes per row */
X    chrs_per_row = R_BYTES(wp);
X
X /* determine the offset from begining of the buffer for this line */
X    row_offst = WIND_POS(wp) + (row * chrs_per_row);
X
X /* search for and point to first character in buffer to be printed */
X    cur_line = wp -> w_linep;   /* start with current first window line */
X    while (TRUE)
X        {                       /* find line with desired character */
X        if (cur_line == wp -> w_bufp -> b_linep)
X            {                   /* at end of buffer? */
X            return (FALSE);
X            }
X        if (cur_line -> l_file_offset > row_offst)
X            {
X            /* if less than current line */
X            cur_line = cur_line -> l_bp;/* step back */
X            }
X        else
X            if ((cur_line -> l_file_offset + cur_line -> l_used) <= row_offst)
X                {
X                cur_line = cur_line -> l_fp;/* step ahead */
X                }
X            else
X                break;
X        }
X
X    lin_offset = row_offst - cur_line -> l_file_offset;/* offset into line */
X
X /* get index into the current line to start reading the current row's data */
X /* copy line text into buffer */
X    chrs_in_lin = fill_buf (wp, cur_line, lin_offset, w_buf, chrs_per_row);
X
X    /* limit line length to screen width, used in TEXT mode only */
X    if (chrs_in_lin > NCOL)
X        chrs_in_lin = NCOL;
X
X /* Clear the line to spaces */
X    for (i = 0; i < NCOL; i++)
X        {
X        vp -> v_text[i] = ' ';
X        }
X    switch (mode)
X        {
X        case TEXT:
X            break;
X        case ASCII: 
X        case EBCDIC: 
X        case BINARY: 
X        case HEX: 
X        /* print the row offset from the start of the file in HEX */
X            sprintf (vp -> v_text, MSG_11lX, row_offst);/* to vid buf */
X            break;
X        case OCTAL: 
X        /* print the row offset from the start of the file */
X            sprintf (vp -> v_text, MSG_11lo, row_offst);/* to vid buf */
X            break;
X        case DECIMAL: 
X        /* print the row offset from the start of the file */
X            sprintf (vp -> v_text, MSG_11ld, row_offst);/* to vid buf */
X            break;
X#if RUNCHK
X        default:
X            writ_echo (ERR_disp_1);
X            break;
X#endif
X        }
X
X /* print the binary data to the text line */
X    bin_to_text (w_buf, vp -> v_text, chrs_in_lin,
X            wp -> w_fmt_ptr);
X
X    vtcol = NCOL;
X	return (TRUE);
X}
X
X/*
X*   Print the contents of then binary data buffer bin_buf
X*   into the proper mode of text into txt_buf.
X*   Process 'len' bytes.
X*
X*   input:
X*           bin_buf     pointer to buffer of binary data to process.
X*           txt_buf     pointer to output buffer to print text result into.
X*           len         length in bytes of data in bin_buf to process.
X*           fmt_ptr     pointer to a ROW_FMT to use to format the data
X*                       conversion and printing process.
X*   output:
X*           none.       
X*/
X
Xvoid bin_to_text (bin_buf, txt_buf, len, fmt_ptr)
X
Xchar   *bin_buf,
X       *txt_buf;
Xuint    len;
XROW_FMT *fmt_ptr;
X
X{
X    uchar   i,
X            ch,
X            k,
X            j,
X            mode,
X            size,
X            *posn;
X    uint    temp_int;
X    ulong   temp_long;
X
X    mode = fmt_ptr -> r_type;   /* get type of format structure */
X    size = fmt_ptr -> r_size;   /* get size of format structure */
X    posn = fmt_ptr -> r_positions;/* pointer to array of display positions */
X
X    switch (mode)
X        {
X        case TEXT: 
X        case ASCII: 
X            for (i = 0; i < len; i++)
X                {
X                ch = bin_buf[i];
X                if ((ch >= ' ') && (ch < 0x7f))
X                    txt_buf[posn[0] + i] = ch;
X                else
X                    txt_buf[posn[0] + i] = '.';
X                }
X            break;
X
X        case EBCDIC: 
X            for (i = 0; i < len; i++)
X                {
X                txt_buf[posn[0] + i] =
X                    0xff & ebcdic_table[0xff & bin_buf[i]];
X                }
X            break;
X
X        case OCTAL: 
X            switch (size)
X                {
X                case BYTES:     /* print octal bytes */
X                    for (i = 0; i < len; i++)
X                        {
X                        sprintf (&txt_buf[
X                                    posn[i]], MSG_03o, 0xff & bin_buf[i]);
X                        }
X                    break;
X
X                case WORDS:     /* print octal words */
X                    k = 0;
X                    for (i = 0; i < len;
X                            i += 2)
X                        {
X                        temp_int = get_int (&bin_buf[i]);
X                        sprintf (&txt_buf[posn[k++]], MSG_06o, temp_int);
X                        }
X                    break;
X
X                case DWORDS:    /* print octal double words */
X                    k = 0;
X                    for (i = 0; i < len;
X                            i += 4)
X                        {
X                        temp_long = get_long (&bin_buf[i]);
X                        sprintf (&txt_buf[posn[k++]], MSG_011lo, temp_long);
X                        }
X                    break;
X                }
X            break;
X
X        case DECIMAL: 
X            switch (size)
X                {
X                case BYTES:     /* print decimal bytes */
X                    for (i = 0; i < len; i++)
X                        {
X                        sprintf (&txt_buf[
X                                    posn[i]], MSG_03u, 0xff & bin_buf[i]);
X                        }
X                    break;
X
X                case WORDS:     /* print decimal words */
X                    k = 0;
X                    for (i = 0; i < len;
X                            i += 2)
X                        {
X                        temp_int = get_int (&bin_buf[i]);
X                        sprintf (&txt_buf[
X                                    posn[k++]], MSG_05u, temp_int);
X                        }
X                    break;
X
X                case DWORDS:    /* print decimal double words */
X                    k = 0;
X                    for (i = 0; i < len; i += 4)
X                        {
X                        temp_long = get_long (&bin_buf[i]);
X                        sprintf (&txt_buf[
X                                    posn[k++]], MSG_010lu, temp_long);
X                        }
X                    break;
X                }
X            break;
X
X        case HEX: 
X            switch (size)
X                {
X                case BYTES:     /* print hex bytes and ascii chars */
X                    for (i = 0; i < len; i++)
X                        {
X                        if ((bin_buf[i] >= ' ') && (bin_buf[i] < 0x7f))
X                            txt_buf[posn[i + 16]] = 0xff & bin_buf[i];
X                        else
X                            txt_buf[posn[i + 16]] = '.';
X                        sprintf (&txt_buf[posn[i]], MSG_02X, 0xff & bin_buf[i]);
X                        }
X                    break;
X
X                case WORDS:     /* print hex words */
X                    k = 0;
X                    for (i = 0; i < len; i += 2)
X                        {
X                        temp_int = get_int (&bin_buf[i]);
X                        sprintf (&txt_buf[
X                                    posn[k++]], MSG_04X, temp_int);
X                        }
X                    break;
X
X                case DWORDS:    /* print hex double words */
X                    k = 0;
X                    for (i = 0; i < len; i += 4)
X                        {
X                        temp_long = get_long (&bin_buf[i]);
X                        sprintf (&txt_buf[
X                                    posn[k++]], MSG_08lX, temp_long);
X                        }
X                    break;
X                }
X            break;
X
X        case BINARY: 
X            switch (size)
X                {
X                case BYTES:     /* print binary bits */
X                    for (i = 0; i < len; i++)
X                        {
X                        ch = bin_buf[i];/* get char to convert */
X                        for (k = 0; k < 8; k++)
X                            {
X                            if (ch & 0x80)
X                                txt_buf[posn[i] + k]
X                                    = '1';
X                            else
X                                txt_buf[posn[i] + k]
X                                    = '0';
X                            ch = ch << 1;/* slide next bit into place */
X                            }
X                        }
X                    break;
X
X                case WORDS: 
X                    j = 0;
X                    for (i = 0; i < len; i += 2)
X                        {
X                        temp_int = get_int (&bin_buf[i]);
X
X                        for (k = 0; k < 16; k++)
X                            {
X                            if (temp_int & 0x8000)
X                                txt_buf[posn[j] + k]
X                                    = '1';
X                            else
X                                txt_buf[posn[j] + k]
X                                    = '0';
X                            temp_int = temp_int << 1;
X                        /* slide next bit into place */
X                            }
X                        j++;
X                        }
X                    break;
X
X                case DWORDS: 
X                    j = 0;
X                    for (i = 0; i < len; i += 4)
X                        {
X                        temp_long = get_long (&bin_buf[i]);
X                        for (k = 0; k < 32; k++)
X                            {
X                            if (temp_long & 0x80000000)
X                                txt_buf[posn[j] + k]
X                                    = '1';
X                            else
X                                txt_buf[posn[j] + k]
X                                    = '0';
X                            temp_long = temp_long << 1;
X                        /* slide next bit into place */
X                            }
X                        j++;
X                        }
X                    break;
X                }
X            break;
X#if RUNCHK
X        default:
X            writ_echo (ERR_disp_2);
X            break;
X#endif
X        }
X    len *= (fmt_ptr -> r_chr_per_u + 1);
X /* Clean up any garbage characters left by the sprintf's */
X    for (i = 0; i < NCOL; i++)
X        {
X        if (txt_buf[i] == 0)
X            txt_buf[i] = ' ';
X        }
X}
X
X/*
X*   Get an int from the buffer.
X*   Perform the Intel byte shuffle if necessary
X*/
X
XD16 get_int (w_buf)
Xuchar  *w_buf;
X
X{
X    int     temp_int;
X
X    if (curwp -> w_intel_mode)
X        {
X        temp_int = 0xff & w_buf[1];
X        temp_int <<= 8;
X        temp_int |= 0xff & w_buf[0];
X        }
X    else
X        {
X        temp_int = 0xff & w_buf[0];
X        temp_int <<= 8;
X        temp_int |= 0xff & w_buf[1];
X        }
X    return (temp_int);
X}
X
X/*
X*   Get an long from the buffer.
X*   Perform the Intel byte shuffle if necessary
X*/
X
XD32 get_long (w_buf)
Xuchar  *w_buf;
X
X{
X    long    temp_long;
X
X    if (curwp -> w_intel_mode)
X        {
X        temp_long = 0xff & w_buf[3];
X        temp_long <<= 8;
X        temp_long |= 0xff & w_buf[2];
X        temp_long <<= 8;
X        temp_long |= 0xff & w_buf[1];
X        temp_long <<= 8;
X        temp_long |= 0xff & w_buf[0];
X        }
X    else
X        {
X        temp_long = 0xff & w_buf[0];
X        temp_long <<= 8;
X        temp_long |= 0xff & w_buf[1];
X        temp_long <<= 8;
X        temp_long |= 0xff & w_buf[2];
X        temp_long <<= 8;
X        temp_long |= 0xff & w_buf[3];
X        }
X    return (temp_long);
X}
X
X
X/*
X*   Copy a length of bytes from the buffer LINEs into the designated
X*   buffer.   If the current LINE does not have enough bytes then
X*   advance to the next.   Return the actual number of bytes copied.
X*   The number copied would be less than the number requested if
X*   end of file is reached.
X*/
X
Xuint    fill_buf (wp, lin, lin_off, w_buff, cnt)
XWINDOW  *wp;
XLINE    *lin;
Xuint    lin_off,
X        cnt;
Xchar    *w_buff;
X{
X    REGI uint   src,
X                dest,
X                i;
X
X    src = lin_off;              /* initialize source line index */
X    dest = 0;                   /* initialize destination buffer index */
X
X    while (TRUE)
X        {
X        while (src < lin -> l_used)
X            {
X            w_buff[dest++] = lin -> l_text[src++];/* copy byte */
X
X            if (dest == cnt)
X                {               /* if done */
X                return (cnt);   /* then leave */
X                }
X            }
X        if (R_TYPE(curwp) == TEXT)
X            return (dest);   /* in text mode don't advance to next line */
X
X        lin = lin -> l_fp;      /* move to the next line */
X        if (lin == wp -> w_bufp -> b_linep)
X            {                   /* if past last line */
X            {
X                for (i = dest; i < cnt; ++i)
X                    w_buff[i] = 0;/* fill rest of buffer with zeros */
X                return (dest);  /* return number of chars copied */
X            }
X            }
X        src = 0;                /* start next LINE at first byte */
X        }
X}
X
X/*
X* Erase from the end of the
X* software cursor to the end of the
X* line on which the software cursor is
X* located. The display routines will decide
X* if a hardware erase to end of line command
X* should be used to display this.
X*/
Xvoid vteeol ()
X{
X    register    VIDEO * vp;
X
X    vp = vscreen[vtrow];
X    while (vtcol < ncol)
X        vp -> v_text[vtcol++] = ' ';
X}
X
X/*
X* Make sure that the display is
X* right. This is a three part process. First,
X* scan through all of the windows looking for dirty
X* ones. Check the framing, and refresh the screen.
X* Second, make the
X* virtual and physical screens the same.
X*/
Xvoid update ()
X{
X    register    LINE * lp;
X    register    WINDOW * wp;
X    register    VIDEO * vp1;
X    register    VIDEO * vp2;
X    register uint    i;
X    register int    j,
X                    k;
X    register int    c;
X    register int    hflag;
X    register int    offs;
X    register int    size;
X
X    hflag = FALSE;              /* Not hard.            */
X    wp = wheadp;
X    while (wp != NULL)
X        {
X    /* is this window to be displayed in linked mode */
X        if ((curbp -> b_flag & BFLINK) &&
X                (wp -> w_bufp == curbp))
X            {                   /* move dot to current window's dot position */
X            wp -> w_dotp = curwp -> w_dotp;
X            wp -> w_doto = curwp -> w_doto;
X            move_ptr (wp, 0L, TRUE, TRUE, TRUE); /* insure dot is aligned */
X            wind_on_dot (wp);   /* move window to new dot position */
X            }
X
X        if (wp -> w_flag != 0)
X
X            {                   /* Need update.         */
X            move_ptr (wp, 0L, FALSE, TRUE, TRUE); /* window on row boundary */
X            move_ptr (wp, 0L, TRUE, TRUE, TRUE); /* dot on unit boundary */
X            if ((wp -> w_flag & WFFORCE) == 0)
X                {
X                wind_on_dot (wp);/* position window on dot */
X                }
X            i = get_currow (wp); /* Redo this one line, mabey.    */
X            if ((wp -> w_flag & ~WFMODE) == WFEDIT)
X                {
X                vscreen[i] -> v_color = CTEXT;
X                vscreen[i] -> v_flag |= (VFCHG | VFHBAD);
X                vtmove (i, 0);
X                vtputd (wp, i - wp -> w_toprow);/* print line to the screen */
X                }
X            else
X                if ((wp -> w_flag & ~WFMODE) == WFMOVE)
X                    {
X                    while (i < wp -> w_toprow + wp -> w_ntrows)
X                        {
X                        /* paint entire window */
X                        vscreen[i] -> v_color = CTEXT;
X                        vscreen[i] -> v_flag |= (VFCHG | VFHBAD);
X                        vtmove (i, 0);
X                        /* print line to the screen */
X                        if (!vtputd (wp, i - wp -> w_toprow))
X                            vteeol ();
X                        ++i;
X                        }
X                    }
X                else
X                    if ((wp -> w_flag & (WFEDIT | WFHARD)) != 0)
X                        {
X                        hflag = TRUE;
X                        i = wp -> w_toprow;
X                        while (i < wp -> w_toprow + wp -> w_ntrows)
X                            {
X                            /* paint entire window */
X                            vscreen[i] -> v_color = CTEXT;
X                            vscreen[i] -> v_flag |= (VFCHG | VFHBAD);
X                            vtmove (i, 0);
X                            /* print line to the screen */
X                            if (!vtputd (wp, i - wp -> w_toprow))
X                                vteeol ();
X                            ++i;
X                            }
X                        }
X            if ((wp -> w_flag & WFMODE) ||
X                    (wp -> w_flag & WFMOVE) ||
X                    (wp -> w_flag & WFHARD))
X                modeline (wp);
X            wp -> w_flag = 0;
X            }
X        wp = wp -> w_wndp;
X        }
X    if (sgarbf != FALSE)
X        {                       /* Screen is garbage.   */
X        sgarbf = FALSE;         /* Erase-page clears    */
X        epresf = FALSE;         /* the message area.    */
X        tttop = HUGE;           /* Forget where you set */
X        ttbot = HUGE;           /* scroll region.       */
X        tthue = CNONE;          /* Color unknown.       */
X        ttmove (0, 0);
X        tteeop ();
X#if MSDOS
X        if (mem_map)
X            {
X            for (i = 0; i < nrow; ++i)
X                {
X                mem_line (i, vscreen[i]);
X                }
X            }
X        else
X            {
X#endif
X            for (i = 0; i < nrow; ++i)
X                {
X                uline (i, vscreen[i], &blanks);
X                ucopy (vscreen[i], pscreen[i]);
X                }
X#if MSDOS
X            }
X#endif
X        ttmove (get_currow (curwp), get_curcol (curwp));
X        ttflush ();
X        return;
X        }
X#if     GOSLING
X    if (hflag != FALSE)
X        {                       /* Hard update?         */
X        for (i = 0; i < nrow; ++i)
X            {                   /* Compute hash data.   */
X            hash (vscreen[i]);
X            hash (pscreen[i]);
X            }
X        offs = 0;               /* Get top match.       */
X        while (offs != nrow)
X            {
X            vp1 = vscreen[offs];
X            vp2 = pscreen[offs];
X            if (vp1 -> v_color != vp2 -> v_color
X                    || vp1 -> v_hash != vp2 -> v_hash)
X                break;
X#if MSDOS
X            if (mem_map)
X                mem_line (offs, vp1);
X            else
X#endif
X                {
X                uline (offs, vp1, vp2);
X                ucopy (vp1, vp2);
X                }
X            ++offs;
X            }
X        if (offs == nrow - 1)
X            {                   /* Might get it all.    */
X            ttmove (get_currow (curwp), get_curcol (curwp));
X            ttflush ();
X            return;
X            }
X        size = nrow;        /* Get bottom match.    */
X        while (size != offs)
X            {
X            vp1 = vscreen[size - 1];
X            vp2 = pscreen[size - 1];
X            if (vp1 -> v_color != vp2 -> v_color
X                    || vp1 -> v_hash != vp2 -> v_hash)
X                break;
X#if MSDOS
X            if (mem_map)
X                mem_line (size - 1, vp1);
X            else
X#endif
X                {
X                uline (size - 1, vp1, vp2);
X                ucopy (vp1, vp2);
X                }
X            --size;
X            }
X        if ((size -= offs) == 0)/* Get screen size.     */
X            abort ();
X        setscores (offs, size); /* Do hard update.      */
X        traceback (offs, size, size, size);
X        for (i = 0; i < size; ++i)
X            ucopy (vscreen[offs + i], pscreen[offs + i]);
X        ttmove (get_currow (curwp), get_curcol (curwp));
X        ttflush ();
X        return;
X        }
X#endif
X    for (i = 0; i < nrow; ++i)
X        {                       /* Easy update.         */
X        vp1 = vscreen[i];
X        vp2 = pscreen[i];
X        if ((vp1 -> v_flag & VFCHG) != 0)
X            {
X#if MSDOS
X            if (mem_map)
X                mem_line (i, vp1);
X            else
X#endif
X                {
X                uline (i, vp1, vp2);
X                ucopy (vp1, vp2);
X                }
X            }
X        }
X    ttmove (get_currow (curwp), get_curcol (curwp));
X    ttflush ();
X}
X/*
X*   Get the window relative row in which the cursor will
X*   appear. pvr
X*/
Xuint    get_currow (wp)
X        WINDOW * wp;
X{
X    A32    row;
X /* number of bytes from start of window */
X    row = DOT_POS(wp) - WIND_POS(wp);
X /* number of rows down in window */
X    row /= R_BYTES(wp);
X    row += wp -> w_toprow;
X#if RUNCHK
X    if (row < wp -> w_toprow)
X        printf (ERR_disp_3);
X    if (row > (wp -> w_ntrows + wp -> w_toprow))
X        printf (ERR_disp_4);
X#endif
X    return (row & 0xffff);
X}
X
X/*
X*   Get the window relative column in which the cursor will
X*   appear. pvr
X*/
Xuint    get_curcol (wp)
X        WINDOW * wp;
X{
X    long    offset,
X            index;
X    uint    b_per_u, pos;
X
X    b_per_u = R_B_PER_U(wp);
X /* dot offset from start of buffer */
X    offset = DOT_POS(wp);
X    offset -= wp -> w_disp_shift;
X    offset &= ~(b_per_u - 1);
X /* calculate mod of the current file position */
X    index = offset & (R_BYTES(wp) - 1);
X    index /= b_per_u;
X    /* limit to window width */
X    if (index >= NCOL)
X        index = NCOL;
X    pos = wp -> w_fmt_ptr -> r_positions[index] + wp -> w_unit_offset;
X    return (pos);
X}
X#if MSDOS
Xvoid    mem_line (row, vvp)
Xint     row;
XVIDEO * vvp;
X    {
X    vvp -> v_flag &= ~VFCHG;    /* Changes done.        */
X    ttcolor (vvp -> v_color);
X    putline (row + 1, 1, ncol, &vvp -> v_text[0]);
X    }
X#endif
X/*
X* Update a saved copy of a line,
X* kept in a VIDEO structure. The "vvp" is
X* the one in the "vscreen". The "pvp" is the one
X* in the "pscreen". This is called to make the
X* virtual and physical screens the same when
X* display has done an update.
X*/
Xvoid ucopy (vvp, pvp)
Xregister    VIDEO * vvp;
Xregister    VIDEO * pvp;
X{
X    register int    i;
X
X    vvp -> v_flag &= ~VFCHG;    /* Changes done.        */
X    pvp -> v_flag = vvp -> v_flag;/* Update model.        */
X    pvp -> v_hash = vvp -> v_hash;
X    pvp -> v_cost = vvp -> v_cost;
X    pvp -> v_color = vvp -> v_color;
X    for (i = 0; i < ncol; ++i)
X        pvp -> v_text[i] = vvp -> v_text[i];
X}
X
X/*
X* Update a single line. This routine only
X* uses basic functionality (no insert and delete character,
X* but erase to end of line). The "vvp" points at the VIDEO
X* structure for the line on the virtual screen, and the "pvp"
X* is the same for the physical screen. Avoid erase to end of
X* line when updating CMODE color lines, because of the way that
X* reverse video works on most terminals.
X*/
Xvoid uline (row, vvp, pvp)
XVIDEO * vvp;
XVIDEO * pvp;
X{
X    register char  *cp1;
X    register char  *cp2;
X    register char  *cp3;
X    register char  *cp4;
X    register char  *cp5;
X    register int    nbflag;
X
X    if (vvp -> v_color != pvp -> v_color)
X        {                       /* Wrong color, do a    */
X        ttmove (row, 0);        /* full redraw.         */
X        ttcolor (vvp -> v_color);
X        cp1 = &vvp -> v_text[0];
X        cp2 = &vvp -> v_text[ncol];
X        while (cp1 != cp2)
X            {
X            ttputc (*cp1++);
X            ++ttcol;
X            }
X        return;
X        }
X    cp1 = &vvp -> v_text[0];    /* Compute left match.  */
X    cp2 = &pvp -> v_text[0];
X    while (cp1 != &vvp -> v_text[ncol] && cp1[0] == cp2[0])
X        {
X        ++cp1;
X        ++cp2;
X        }
X    if (cp1 == &vvp -> v_text[ncol])/* All equal.           */
X        return;
X    nbflag = FALSE;
X    cp3 = &vvp -> v_text[ncol]; /* Compute right match. */
X    cp4 = &pvp -> v_text[ncol];
X    while (cp3[-1] == cp4[-1])
X        {
X        --cp3;
X        --cp4;
X        if (cp3[0] != ' ')      /* Note non-blanks in   */
X            nbflag = TRUE;      /* the right match.     */
X        }
X    cp5 = cp3;                  /* Is erase good?       */
X    if (nbflag == FALSE && vvp -> v_color == CTEXT)
X        {
X        while (cp5 != cp1 && cp5[-1] == ' ')
X            --cp5;
X    /* Alcyon hack */
X        if ((int) (cp3 - cp5) <= tceeol)
X            cp5 = cp3;
X        }
X /* Alcyon hack */
X    ttmove (row, (int) (cp1 - &vvp -> v_text[0]));
X    ttcolor (vvp -> v_color);
X    while (cp1 != cp5)
X        {
X        ttputc (*cp1++);
X        ++ttcol;
X        }
X    if (cp5 != cp3)             /* Do erase.            */
X        tteeol ();
X}
X
X/*
X* Redisplay the mode line for
X* the window pointed to by the "wp".
X* This is the only routine that has any idea
X* of how the modeline is formatted. You can
X* change the modeline format by hacking at
X* this routine. Called by "update" any time
X* there is a dirty window.
X*/
X
Xvoid modeline (wp)
Xregister    WINDOW * wp;
X{
X    register char  *cp,
X                    mode,
X                    size,
X                    u_posn,
X                   *s;
X    register int    c;
X    register int    n;
X    register    BUFFER * bp;
X    register    A32 posn;
X
X    static char posn_buf[30] =
X    {0
X    };                          /* krw */
X
X    mode = wp -> w_fmt_ptr -> r_type;/* get type of format structure */
X    size = wp -> w_fmt_ptr -> r_size;/* get size of format structure */
X
X    n = wp -> w_toprow + wp -> w_ntrows;/* Location.            */
X    vscreen[n] -> v_color = CMODE;/* Mode line color.     */
X    vscreen[n] -> v_flag |= (VFCHG | VFHBAD);/* Recompute, display.  */
X    vtmove (n, 0);              /* Seek to right line.  */
X    bp = wp -> w_bufp;
X
X    cp = MSG_prog_name;               /* Program name.  pvr    */
X    n = 5;         
X    while ((c = *cp++) != 0)
X        {
X        vtputc (c);
X        ++n;
X        }
X
X    if ((bp -> b_flag & BFBAD) != 0)/* "?" if trashed.      */
X        vtputc ('?');
X    else
X        vtputc (' ');
X
X    if ((bp -> b_flag & BFCHG) != 0)/* "*" if changed.      */
X        vtputc ('*');
X    else
X        vtputc (' ');
X
X    if (insert_mode)            /* "I" if insert mode  */
X        vtputc ('I');
X    else
X        vtputc ('O');
X
X    if (bp == blistp)
X        {                       /* special list */
X        cp = MSG_disp_b_lst;
X        while ((c = *cp++) != 0)
X            {
X            vtputc (c);
X            ++n;
X            }
X        goto pad;
X        }
X
X/* Buffer name */
X    vtputc (' ');
X    ++n;
X    cp = &bp -> b_bname[0];
X    while ((c = *cp++) != 0)
X        {
X        vtputc (c);
X        ++n;
X        }
X    while ((int) (cp - &bp -> b_bname[0]) < NBUFN)
X        {
X        vtputc (' ');
X        n++;
X        cp++;
X        }
X 
X /* File name.           */
X    vtputc (' ');
X    ++n;
X    cp = MSG_file;
X    while ((c = *cp++) != 0)
X        {
X        vtputc (c);
X        ++n;
X        }
X    cp = &bp -> b_fname[0];
X    while ((c = *cp++) != 0)
X        {
X        vtputc (c);
X        ++n;
X        }
X    cp--;
X    while ((int) (cp - &bp -> b_fname[0]) < NFILE)
X        {
X        vtputc (' ');
X        n++;
X        cp++;
X        }
X
X    if (bp -> b_flag & BFVIEW)
X        s = MSG_RO;
X    else if (bp -> b_flag & BFSLOCK)
X        s = MSG_WL;
X    else
X        s = MSG_RW;
X
X    while (*s)
X        {                       /* krw */
X        vtputc (*s++);
X        ++n;
X        }
X
X    if (auto_update && !(bp -> b_flag & BFVIEW) && bp -> b_bname[0])/* jam */
X        s = MSG_AU;
X    else
X        s = MSG_NOT_AU;
X    for (; *s && n < NCOL;)
X        {
X        vtputc (*s++);
X        ++n;
X        }
X
X /* Insert current dot position into mode line. */
X    posn = DOT_POS(wp);
X    u_posn = R_CHR_PER_U(wp) - wp -> w_unit_offset - 1;
X    if (u_posn < 0)
X        u_posn = 0;
X    switch (mode)
X        {
X        case TEXT: 
X        case ASCII: 
X            sprintf (posn_buf, MSG_curs_asc, posn);
X            break;
X        case EBCDIC: 
X            sprintf (posn_buf, MSG_curs_ebc, posn);
X            break;
X        case HEX: 
X            sprintf (posn_buf, MSG_curs_hex, posn, u_posn);
X            break;
X        case BINARY: 
X            sprintf (posn_buf, MSG_curs_bin, posn, u_posn);
X            break;
X        case DECIMAL: 
X            sprintf (posn_buf, MSG_curs_dec, posn, u_posn);
X            break;
X        case OCTAL: 
X            sprintf (posn_buf, MSG_curs_oct, posn, u_posn);
X            break;
X#if RUNCHK
X        default:
X            writ_echo (ERR_disp_5);
X            break;
X#endif
X        }
X
X    cp = posn_buf;
X    while ((c = *cp++) != 0)
X        {
X        vtputc (c);
X        ++n;
X        }
X
X
X    if ((mode == HEX) ||
X            (mode == DECIMAL) ||
X            (mode == OCTAL))
X        {
X        switch (size)
X            {
X            case BYTES: 
X                sprintf (posn_buf, MSG_siz_8);
X                break;
X            case WORDS: 
X                sprintf (posn_buf, MSG_siz_16);
X                break;
X            case DWORDS: 
X                sprintf (posn_buf, MSG_siz_32);
X                break;
X#if RUNCHK
X            default:
X                writ_echo (ERR_disp_6);
X                break;
X#endif
X            }
X        }
X    else
X        sprintf (posn_buf, MSG_siz_null);
X
X    cp = posn_buf;
X    while ((c = *cp++) != 0)
X        {
X        vtputc (c);
X        ++n;
X        }
X
X    if (wp -> w_intel_mode)
X        sprintf (posn_buf, MSG_int_shift, wp -> w_disp_shift);
X    else
X        sprintf (posn_buf, MSG_mot_shift, wp -> w_disp_shift);
X    cp = posn_buf;
X    while ((c = *cp++) != 0)
X        {
X        vtputc (c);
X        ++n;
X        }
X
X
X /* pad out */
Xpad: 
X    while (n < ncol)
X        {
X        vtputc (' ');
X        ++n;
X        }
X}
X
X/*
X* write text to the echo line 
X*/
Xvoid    writ_echo (buf)
Xchar    *buf;
X    {
X    int     i, len;
X    char    *vpp;
X    bool    fill_spac;
X
X    fill_spac = FALSE;
X    vpp = vscreen[nrow - 1] -> v_text; 
X    vscreen[nrow - 1] -> v_color = CTEXT;
X    vscreen[nrow - 1] -> v_flag |= VFCHG;
X    epresf = TRUE;
X
X    for (i = 0; i < NCOL; i++)
X        {
X        if (buf[i] == 0)
X            fill_spac = TRUE;
X        if (fill_spac)
X            vpp[i] = ' ';    
X        else    
X            vpp[i] = buf[i];    
X        }
X#if MSDOS
X    if (mem_map)
X        {
X        mem_line (nrow - 1, vscreen[nrow - 1]);
X        }
X    else
X#endif
X        {
X        uline (nrow - 1, vscreen[nrow - 1], pscreen[nrow - 1]);
X        uline (nrow - 1, vscreen[nrow - 1], &blanks);
X        ucopy (vscreen[nrow - 1], pscreen[nrow - 1]);
X		ttflush ();
X        }
X    }
X
X#if     GOSLING
X/*
X* Compute the hash code for
X* the line pointed to by the "vp". Recompute
X* it if necessary. Also set the approximate redisplay
X* cost. The validity of the hash code is marked by
X* a flag bit. The cost understand the advantages
X* of erase to end of line. Tuned for the VAX
X* by Bob McNamara; better than it used to be on
X* just about any machine.
X*/
Xvoid hash (vp)
Xregister    VIDEO * vp;
X{
X    register int    i;
X    register int    n;
X    register char  *s;
X
X    if ((vp -> v_flag & VFHBAD) != 0)
X        {                       /* Hash bad.            */
X        s = &vp -> v_text[ncol - 1];
X        for (i = ncol; i != 0; --i, --s)
X            if (*s != ' ')
X                break;
X        n = ncol - i;           /* Erase cheaper?       */
X        if (n > tceeol)
X            n = tceeol;
X        vp -> v_cost = i + n;   /* Bytes + blanks.      */
X        for (n = 0; i != 0; --i, --s)
X            n = (n << 5) + n + *s;
X        vp -> v_hash = n;       /* Hash code.           */
X        vp -> v_flag &= ~VFHBAD;/* Flag as all done.    */
X        }
X}
X
X/*
X* Compute the Insert-Delete
X* cost matrix. The dynamic programming algorithm
X* described by James Gosling is used. This code assumes
X* that the line above the echo line is the last line involved
X* in the scroll region. This is easy to arrange on the VT100
X* because of the scrolling region. The "offs" is the origin 0
X* offset of the first row in the virtual/physical screen that
X* is being updated; the "size" is the length of the chunk of
X* screen being updated. For a full screen update, use offs=0
X* and size=nrow-1.
X*
X* Older versions of this code implemented the score matrix by
X* a two dimensional array of SCORE nodes. This put all kinds of
X* multiply instructions in the code! This version is written to
X* use a linear array and pointers, and contains no multiplication
X* at all. The code has been carefully looked at on the VAX, with
X* only marginal checking on other machines for efficiency. In
X* fact, this has been tuned twice! Bob McNamara tuned it even
X* more for the VAX, which is a big issue for him because of
X* the 66 line X displays.
X*
X* On some machines, replacing the "for (i=1; i<=size; ++i)" with
X* i = 1; do 
X    {    }while (++i <=size)" will make the code quite a
X* bit better; but it looks ugly.
X*/
Xvoid setscores (offs, size)
X{
X    register    SCORE * sp;
X    register int    tempcost;
X    register int    bestcost;
X    register int    j;
X    register int    i;
X    register    VIDEO ** vp;
X    register    VIDEO ** pp;
X    register    SCORE * sp1;
X    register    VIDEO ** vbase;
X    register    VIDEO ** pbase;
X
X    vbase = &vscreen[offs - 1]; /* By hand CSE's.       */
X    pbase = &pscreen[offs - 1];
X    score[0].s_itrace = 0;      /* [0, 0]               */
X    score[0].s_jtrace = 0;
X    score[0].s_cost = 0;
X    sp = &score[1];             /* Row 0, inserts.      */
X    tempcost = 0;
X    vp = &vbase[1];
X    for (j = 1; j <= size; ++j)
X        {
X        sp -> s_itrace = 0;
X        sp -> s_jtrace = j - 1;
X        tempcost += tcinsl;
X        tempcost += (*vp) -> v_cost;
X        sp -> s_cost = tempcost;
X        ++vp;
X        ++sp;
X        }
X    sp = &score[NROW];          /* Column 0, deletes.   */
X    tempcost = 0;
X    for (i = 1; i <= size; ++i)
X        {
X        sp -> s_itrace = i - 1;
X        sp -> s_jtrace = 0;
X        tempcost += tcdell;
X        sp -> s_cost = tempcost;
X        sp += NROW;
X        }
X    sp1 = &score[NROW + 1];     /* [1, 1].              */
X    pp = &pbase[1];
X    for (i = 1; i <= size; ++i)
X        {
X        sp = sp1;
X        vp = &vbase[1];
X        for (j = 1; j <= size; ++j)
X            {
X            sp -> s_itrace = i - 1;
X            sp -> s_jtrace = j;
X            bestcost = (sp - NROW) -> s_cost;
X            if (j != size)      /* Cd(A[i])=0 @ Dis.    */
X                bestcost += tcdell;
X            tempcost = (sp - 1) -> s_cost;
X            tempcost += (*vp) -> v_cost;
X            if (i != size)      /* Ci(B[j])=0 @ Dsj.    */
X                tempcost += tcinsl;
X            if (tempcost < bestcost)
X                {
X                sp -> s_itrace = i;
X                sp -> s_jtrace = j - 1;
X                bestcost = tempcost;
X                }
X            tempcost = (sp - NROW - 1) -> s_cost;
X            if ((*pp) -> v_color != (*vp) -> v_color
X                    || (*pp) -> v_hash != (*vp) -> v_hash)
X                tempcost += (*vp) -> v_cost;
X            if (tempcost < bestcost)
X                {
X                sp -> s_itrace = i - 1;
X                sp -> s_jtrace = j - 1;
X                bestcost = tempcost;
X                }
X            sp -> s_cost = bestcost;
X            ++sp;               /* Next column.         */
X            ++vp;
X            }
X        ++pp;
X        sp1 += NROW;            /* Next row.            */
X        }
X}
X
X/*
X* Trace back through the dynamic programming cost
X* matrix, and update the screen using an optimal sequence
X* of redraws, insert lines, and delete lines. The "offs" is
X* the origin 0 offset of the chunk of the screen we are about to
X* update. The "i" and "j" are always started in the lower right
X* corner of the matrix, and imply the size of the screen.
X* A full screen traceback is called with offs=0 and i=j=nrow-1.
X* There is some do-it-yourself double subscripting here,
X* which is acceptable because this routine is much less compute
X* intensive then the code that builds the score matrix!
X*/
Xvoid traceback (offs, size, i, j)
X{
X    register int    itrace;
X    register int    jtrace;
X    register int    k;
X    register int    ninsl;
X    register int    ndraw;
X    register int    ndell;
X
X    if (i == 0 && j == 0)       /* End of update.       */
X        return;
X    itrace = score[(NROW * i) + j].s_itrace;
X    jtrace = score[(NROW * i) + j].s_jtrace;
X    if (itrace == i)
X        {                       /* [i, j-1]             */
X        ninsl = 0;              /* Collect inserts.     */
X        if (i != size)
X            ninsl = 1;
X        ndraw = 1;
X        while (itrace != 0 || jtrace != 0)
X            {
X            if (score[(NROW * itrace) + jtrace].s_itrace != itrace)
X                break;
X            jtrace = score[(NROW * itrace) + jtrace].s_jtrace;
X            if (i != size)
X                ++ninsl;
X            ++ndraw;
X            }
X        traceback (offs, size, itrace, jtrace);
X        if (ninsl != 0)
X            {
X            ttcolor (CTEXT);
X            ttinsl (offs + j - ninsl, offs + size - 1, ninsl);
X            }
X        do
X            {                   /* B[j], A[j] blank.    */
X            k = offs + j - ndraw;
X            uline (k, vscreen[k], &blanks);
X        } while (--ndraw);
X        return;
X        }
X    if (jtrace == j)
X        {                       /* [i-1, j]             */
X        ndell = 0;              /* Collect deletes.     */
X        if (j != size)
X            ndell = 1;
X        while (itrace != 0 || jtrace != 0)
X            {
X            if (score[(NROW * itrace) + jtrace].s_jtrace != jtrace)
X                break;
X            itrace = score[(NROW * itrace) + jtrace].s_itrace;
X            if (j != size)
X                ++ndell;
X            }
X        if (ndell != 0)
X            {
X            ttcolor (CTEXT);
X            ttdell (offs + i - ndell, offs + size - 1, ndell);
X            }
X        traceback (offs, size, itrace, jtrace);
X        return;
X        }
X    traceback (offs, size, itrace, jtrace);
X    k = offs + j - 1;
X    uline (k, vscreen[k], pscreen[offs + i - 1]);
X}
X#endif
X
X/*
X* Print the current buffer from mark to dot using the 
X* current window's display format.
X* Prompt for file name or io device to print to.
X*/
X
Xbool    print ()
X    {
X    LINE    *dot_l_sav, *mark_l_sav, *wind_l_sav;
X    int     dot_off_sav, mark_off_sav, wind_off_sav, i;
X    char   s;
X    char    fname[NFILEN];
X    register int    nline;
X    char    buf[80], buf1[60];
X
X    /* save the original window state */
X    dot_l_sav = curwp -> w_dotp;
X    dot_off_sav = curwp -> w_doto;
X    mark_l_sav = curwp -> w_markp;
X    mark_off_sav = curwp -> w_marko;
X    wind_l_sav = curwp -> w_linep;
X    wind_off_sav = curwp -> w_loff;
X
X    /* if mark is not set then set it to location zero */
X    if (curwp -> w_markp == NULL)
X        {
X        curwp -> w_markp = curwp -> w_bufp -> b_linep -> l_fp;
X        curwp -> w_marko = 0;
X        }
X
X    nline = 0;
X    if ((s = ereply (MSG_prn_to, fname, NFILEN, NULL)) == ABORT)
X        return (s);
X    adjustcase (fname);
X    if ((s = ffwopen (fname)) != FIOSUC)/* Open writes message. */
X        return (FALSE);
X
X    sprintf (buf, MSG_print1, fname);
X    writ_echo (buf);
X    /* make dot before mark */
X    if (DOT_POS(curwp) > MARK_POS(curwp))
X        swapmark ();    /* make mark first */
X
X    while (DOT_POS(curwp) <= MARK_POS(curwp))
X        {
X        /* check if we should quit */
X        if (ttkeyready ())
X            {
X            ttgetc ();  /* through away char that was struck */
X            break;
X            }
X        nline++;
X        /* move window so that first line is on dot */
X        move_ptr (curwp, DOT_POS(curwp), FALSE, TRUE, FALSE);
X
X        if (vtputd (curwp, 0))   /* print line into video buffer */
X            {
X            for (i = NCOL; (vscreen[vtrow] -> v_text[i] < '!') ||
X                    (vscreen[vtrow] -> v_text[i] > '~'); i--)
X                ;
X            i++;
X            if ((s = ffputline (vscreen[vtrow] -> v_text, i)) != FIOSUC)
X                break;
X            if ((s = ffputline (MSG_disp_r_n, 2)) != FIOSUC)
X                break;
X            }
X        else
X            break;
X        forwline (0, 1, KRANDOM);   /* advance to next line */
X        }
X    ffclose ();
X    sprintf (buf1, MSG_print2, R_POS_FMT(curwp));
X    sprintf (buf, buf1, (long) nline);
X    writ_echo (buf);
X
X    /* restore the original window state */
X    curwp -> w_dotp = dot_l_sav;
X    curwp -> w_doto = dot_off_sav;
X    curwp -> w_markp = mark_l_sav;
X    curwp -> w_marko = mark_off_sav;
X    curwp -> w_linep = wind_l_sav;
X    curwp -> w_loff = wind_off_sav;
X    curwp -> w_flag |= WFHARD;  /* insure that window is still presentable */
X    return (TRUE);
X    }
END_OF_FILE
if test 49122 -ne `wc -c <'display.c'`; then
    echo shar: \"'display.c'\" unpacked with wrong size!
fi
chmod +x 'display.c'
# end of 'display.c'
fi
echo shar: End of archive 10 \(of 10\).
cp /dev/null ark10isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
>>>>>>>>>>>>>>>> Peter Reilley ..... pvr@wang.com <<<<<<<<<<<<<<<<<<<<<<<
                     Well, that about says it.