home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-11-21 | 54.2 KB | 2,228 lines |
- Newsgroups: comp.sources.misc
- From: pvr@wang.com (Peter Reilley)
- Subject: v26i039: beav - Binary file editor and viewer, v1.32, Part03/09
- Message-ID: <1991Nov21.230151.1521@sparky.imd.sterling.com>
- X-Md4-Signature: 15e715dd1a5e532fcd42bad8b38f2c4d
- Date: Thu, 21 Nov 1991 23:01:51 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: pvr@wang.com (Peter Reilley)
- Posting-number: Volume 26, Issue 39
- Archive-name: beav/part03
- Environment: UNIX, AIX, MS-DOS, AMIGA
- Supersedes: beav: Volume 22, Issue 10-18
-
- #! /bin/sh
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: display.c file.c makefile.286
- # Wrapped by kent@sparky on Thu Nov 21 16:47:00 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 3 (of 9)."'
- if test -f 'display.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'display.c'\"
- else
- echo shar: Extracting \"'display.c'\" \(30889 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. The MEMMAP
- X* changes things around for memory mapped video. With
- X* both off, the terminal is a VT52.
- X*/
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- 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
- Xextern char MSG_prn_to[];
- Xextern char MSG_disp_r_n[];
- Xextern char MSG_11lX[];
- Xextern char MSG_11lo[];
- Xextern char MSG_11ld[];
- Xextern char MSG_03o[];
- Xextern char MSG_06o[];
- Xextern char MSG_011lo[];
- Xextern char MSG_03u[];
- Xextern char MSG_05u[];
- Xextern char MSG_010lu[];
- Xextern char MSG_02X[];
- Xextern char MSG_04X[];
- Xextern char MSG_08lX[];
- Xextern char MSG_prog_name[];
- Xextern char MSG_disp_b_lst[];
- Xextern char MSG_file[];
- Xextern char MSG_RO[];
- Xextern char MSG_WL[];
- Xextern char MSG_RW[];
- Xextern char MSG_AU[];
- Xextern char MSG_NOT_AU[];
- Xextern char MSG_curs_asc[];
- Xextern char MSG_curs_ebc[];
- Xextern char MSG_curs_hex[];
- Xextern char MSG_curs_bin[];
- Xextern char MSG_curs_dec[];
- Xextern char MSG_curs_oct[];
- Xextern char MSG_siz_8[];
- Xextern char MSG_siz_16[];
- Xextern char MSG_siz_32[];
- Xextern char MSG_siz_null[];
- Xextern char MSG_int_shift[];
- Xextern char MSG_mot_shift[];
- Xextern char MSG_print1[];
- Xextern char MSG_print2[];
- X#if RUNCHK
- Xextern char ERR_disp_1[];
- Xextern char ERR_disp_2[];
- Xextern char ERR_disp_3[];
- Xextern char ERR_disp_4[];
- Xextern char ERR_disp_5[];
- Xextern char ERR_disp_6[];
- X#endif
- X
- 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/*
- 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 char 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 mode;
- X REGI A32 row_offst;
- X REGI uint chrs_per_row,
- X lin_offset,
- X i,
- X chrs_in_lin;
- X LINE * cur_line;
- X static char w_buf[128]; /* temp buffer for data */
- 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,
- Xcnt;
- 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(wp) == 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}
- Xreturn (0);
- 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 WINDOW * wp;
- X register VIDEO * vp1;
- X register VIDEO * vp2;
- X register uint i;
- X register int hflag;
- 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 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)
- XWINDOW * 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)
- XWINDOW * 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 char c;
- X register int n;
- X register BUFFER * bp;
- X register A32 posn;
- X
- X static char posn_buf[30] =
- X {
- 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;
- 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/*
- 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[NFILEN], buf1[NFILEN];
- 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, S_IREAD | S_IWRITE)) != 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 if (ttgetc () == CTL_G) /* quit if abort was hit */
- 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 30889 -ne `wc -c <'display.c'`; then
- echo shar: \"'display.c'\" unpacked with wrong size!
- fi
- # end of 'display.c'
- fi
- if test -f 'file.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'file.c'\"
- else
- echo shar: Extracting \"'file.c'\" \(19205 characters\)
- sed "s/^X//" >'file.c' <<'END_OF_FILE'
- X/*
- X* File commands.
- X*/
- X#include <sys/types.h>
- X#include <fcntl.h>
- X#include <sys/stat.h>
- X#include "def.h"
- X
- Xchar load_file ();
- Xchar readin ();
- Xvoid makename ();
- Xbool writeout ();
- Xbool parse_f_name ();
- XA32 ffseek ();
- 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_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
- 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 -> b_type = BTFILE;
- 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 err_echo (MSG_cnt_cr);
- X return (FALSE);
- X }
- X if (--curbp -> b_nwnd == 0)
- X {
- X /* Undisplay. */
- X curbp -> b_type = BTFILE;
- 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 WINDOW * wp;
- X register BUFFER * bp;
- X register char s, m;
- X long byte_cnt;
- X LPOS req_chars;
- X char buf[NCOL], buf1[NCOL];
- 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 bp -> b_file_size = 0;
- X bp -> b_type = BTFILE;
- 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 if ((lp1 = lalloc(req_chars)) == NULL)
- X {
- X bp -> b_flag |= BFVIEW; /* if no memory set to read only mode */
- X
- X m = FALSE; /* flag memory allocation error */
- X }
- X else
- X {
- X while ((s = ffgetline (lp1->l_text, lp1->l_size, &lp1->l_used)) == FIOSUC)
- 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 lp1 -> l_file_offset = byte_cnt; /* file offset from begining */
- X byte_cnt += (long) lp1 -> l_used; /* number of bytes read in */
- X start += (long) lp1 -> l_used;
- 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 if ((lp1 = lalloc(req_chars)) == NULL)
- X {
- X bp -> b_flag |= BFVIEW; /* if no memory set to read only mode */
- X
- X m = FALSE; /* flag memory allocation error */
- X break;
- X }
- X if ((byte_cnt & 0x7fff) == 0)
- X {
- X sprintf (buf1, MSG_read_lx, R_POS_FMT(curwp));
- X sprintf (buf, buf1, (ulong)byte_cnt);
- X writ_echo (buf);
- X /* check if we should quit */
- X if (ttkeyready ())
- X {
- X wind_on_dot_all();
- X if (ttgetc () == CTL_G) /* was it an abort key? */
- X {
- X s = FIOERR;
- X break;
- X }
- X }
- X }
- 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 (buf, MSG_no_mem_rd);
- X err_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 /* so tell yank-buffer about it */
- X if ((blistp -> b_nwnd != 0) && /* update buffer display */
- X (blistp -> b_type == BTLIST))
- X listbuffers ();
- X if (s == FIOERR || s == FIOFNF)/* False if error. */
- X return (FALSE);
- 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, S_IREAD | S_IWRITE)) == 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* then a backup copy of the file is made.
- X*/
- Xchar filesave ()
- X{
- X register WINDOW * wp;
- X register char s;
- X struct stat st;
- 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_type == BTSAVE))/* yanked buffer */
- X {
- X writ_echo (MSG_no_fn);
- X }
- X return (FALSE);
- X }
- X st.st_mode = S_IREAD | S_IWRITE; /* set default */
- X#if BACKUP
- X if ((curbp -> b_flag & BFBAK) != 0)
- X {
- X /* get the mode of the file */
- X stat (curbp -> b_fname, &st);
- 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, st.st_mode)) == 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* The file permissions are set as requested.
- X*/
- Xbool writeout (fn, start, end, mode)
- Xchar *fn;
- XA32 start, end;
- Xushort mode;
- X{
- X register int s, num_chars;
- X register LINE * lp;
- X register long nbytes;
- X char buf[NCOL], buf1[NCOL];
- X A32 temp;
- X
- X if ((s = ffwopen (fn, mode)) != 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 (0, 0, 0);
- 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 ((nbytes & 0x7fff) == 0)
- X {
- X sprintf (buf1, MSG_wrot_n, R_POS_FMT(curwp));
- X sprintf (buf, buf1, (ulong)nbytes);
- X writ_echo (buf);
- X /* check if we should quit */
- X if (ttkeyready ())
- X {
- X wind_on_dot_all();
- X if (ttgetc () == CTL_G) /* was it an abort key? */
- X {
- X s = FIOERR;
- X break;
- X }
- X }
- X }
- X }
- X if (s == FIOSUC)
- X {
- X /* No write error. */
- X s = ffclose ();
- X if (s == FIOSUC && kbdmop == NULL)
- X {
- X sprintf (buf1, MSG_wrot_n, R_POS_FMT(curwp));
- X sprintf (buf, buf1, (long) nbytes);
- X writ_echo (buf);
- X }
- X }
- X else /* Ignore close error */
- X ffclose (); /* if a write error. */
- X curbp -> b_file_size = nbytes; /* update file size */
- X if ((blistp -> b_nwnd != 0) && /* update buffer display */
- X (blistp -> b_type == BTLIST))
- X listbuffers ();
- X if (s != FIOSUC) /* Some sort of error. */
- X return (FALSE);
- 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 (curbp -> b_linep -> l_fp); /* 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[NCOL], fmt[NCOL];
- X int i_cnt;
- 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 19205 -ne `wc -c <'file.c'`; then
- echo shar: \"'file.c'\" unpacked with wrong size!
- fi
- # end of 'file.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'\" \(676 characters\)
- sed "s/^X//" >'makefile.286' <<'END_OF_FILE'
- X# This is a makefile for 286 xenix
- XCFLAGS= -O -Ml -DUNIX -DNOPROTO -DNORENAME
- 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 676 -ne `wc -c <'makefile.286'`; then
- echo shar: \"'makefile.286'\" unpacked with wrong size!
- fi
- # end of 'makefile.286'
- fi
- echo shar: End of archive 3 \(of 9\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 9 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-