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 (®ion)) != 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 (®ion)) != 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, ®s, ®s); /* 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, ®s, ®s); /* 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, ®s, ®s); /* 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, ®s, ®s); /* 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, ®s, ®s); /* 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, ®s, ®s); /* 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, ®s, ®s); /* 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.