BEAV, a full featured binary file editor, part 06 of 11
Peter Reilley
pvr at wang.com
Thu Feb 28 07:50:39 AEST 1991
#! /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 11)."
# Contents: buffer.c def_unix.h
# Wrapped by pvr at elf on Wed Feb 27 14:16:49 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_unix.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'def_unix.h'\"
else
echo shar: Extracting \"'def_unix.h'\" \(19462 characters\)
sed "s/^X//" >'def_unix.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 UNIX 1
X#define MSDOS 0
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 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 uint /* 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/*
X * Digital ANSI terminal header file
X */
X#define GOSLING 0 /* Compile in fancy display. */
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#if 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 * 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
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 19462 -ne `wc -c <'def_unix.h'`; then
echo shar: \"'def_unix.h'\" unpacked with wrong size!
fi
chmod +x 'def_unix.h'
# end of 'def_unix.h'
fi
echo shar: End of archive 6 \(of 11\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 11 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
More information about the Alt.sources
mailing list