beav-140/0000755000175000001440000000000010103001472012220 5ustar samusers00000000000000beav-140/amibeav.lnk0000644000175000001440000000044405667134706014366 0ustar samusers00000000000000FROM LIB:c.o+ amiga.o basic.o ebcdic.o fileio.o region.o text.o wangpc.o buffer.o echo.o language.o main.o search.o tty.o window.o cinfo.o extend.o kbd.o spawn.o ttyio.o termio.o tcap.o word.o display.o file.o line.o random.o symbol.o ttykbd.o format.o TO "beav" LIB LIB:lc.lib LIB:amiga.lib beav-140/amiga.c0000644000175000001440000003374505667134706013510 0ustar samusers00000000000000/* -*-C-*- * * Module : amiga.c * * Author : Simon J Raybould. (sie@fulcrum.bt.co.uk). * * Date : Tuesday 11th June 1991. * * Desc : amiga specifics for beav binary editor. * * * This file is public domain and you can do what you want with it, even roll * it up into a ball and toss it for your cat to chase. I accept no * resposibility for it being unfit for any purpose (including a feline toy). * Any bugs you can either fix them yourself or tell me and I'll do it. * Any major fixes should be reported to me and I will inform the main keeper * of beav to be sure they are fixed in the next release. This only applies to * bugs in THIS FILE or in AMIGA sections of other files. Any other bugs to the * original author. * * SJR - 25.Aug.91 * * */ #ifdef AMIGA #include #include #include #include #include #include #include #include "def.h" #define SCRBUFSIZ 1024 /* buffered screen io */ struct NewWindow nw = { 0, 0, 640, 256, -1, -1, NULL, WINDOWDEPTH | WINDOWDRAG | SMART_REFRESH | ACTIVATE | BORDERLESS, NULL, NULL, "BEAV Amiga Port by S.J.Raybould (sie@fulcrum.bt.co.uk) Sep 1991", NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN }; /* Opens/allocations we'll need to clean up */ struct Library *IntuitionBase = NULL; struct Window *win = NULL, *OpenWindow (); struct IOStdReq *writeReq = NULL; /* I/O request block pointer */ struct MsgPort *writePort = NULL; /* replyport for writes */ struct IOStdReq *readReq = NULL;/* I/O request block pointer */ struct MsgPort *readPort = NULL;/* replyport for reads */ struct MsgPort *CreatePort (); BOOL OpenedConsole = FALSE; UBYTE ibuf; BYTE OpenConsole (); void CloseConsole (), QueueRead (), ConWrite (); int nrow; /* Terminal size, rows. */ int ncol; /* Terminal size, columns. */ #ifdef CRAP int tceeol = 3; /* Costs. */ #endif /* CRAP */ int kbdpoll; /* in O_NDELAY mode */ int kbdqp; /* there is a char in kbdq */ char scrbuf[SCRBUFSIZ]; /* buffered screen io */ short scrbufpos = 0; /* current write position */ /* CODE TO REPLACE STUFF IN termio.c */ /* * This function gets called just before we go back home to the command * interpreter. On VMS it puts the terminal back in a reasonable state. * Another no-operation on CPM. */ void ttclose () { /* Put TTY back in sesible state */ if (!(CheckIO (readReq))) AbortIO (readReq); WaitIO (readReq); if (OpenedConsole) CloseConsole (writeReq); if (readReq) DeleteExtIO (readReq); if (readPort) DeletePort (readPort); if (writeReq) DeleteExtIO (writeReq); if (writePort) DeletePort (writePort); if (win) CloseWindow (win); if (IntuitionBase) CloseLibrary (IntuitionBase); } /* * Flush terminal buffer. Does real work where the terminal output is buffered * up. A no-operation on systems where byte at a time terminal I/O is done. */ void ttflush () { if (scrbufpos > 0) { ConWrite (writeReq, scrbuf, scrbufpos); scrbufpos = 0; } } /* * Write a character to the display. On VMS, terminal output is buffered, and * we just put the characters in the big array, after checking for overflow. * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on * MS-DOS (use the very very raw console output routine). */ void ttputc (c) { if (scrbufpos < SCRBUFSIZ) scrbuf[scrbufpos++] = c; else { ConWrite (writeReq, scrbuf, scrbufpos); scrbufpos = 0; scrbuf[scrbufpos++] = c; } } void ttputs (char *str) { while (*str) ttputc (*str++); } /* * Read a character from the terminal, performing no editing and doing no echo * at all. More complex in VMS that almost anyplace else, which figures. Very * simple on CPM, because the system can do exactly what you want. */ ttgetc () { char c, ConGetChar (); static char Buffer[8], ri = 0, wi = 0; if (kbdqp) kbdqp = FALSE; /* If we stil have chars from last time, return them */ if (ri < wi) return Buffer[ri++] & 0x7f; /* Else empty the buffer and start a new read */ ri = wi = 0; c = ConGetChar (readPort, &ibuf); /* * Attempt some translations ! * This is the place to extend, if you wish to add some more. * SEE RKM L&D 1.3 pg 654 for more info. */ if ((unsigned char) c == (unsigned char) 0x9b) { /* ANSI esc start */ c = ConGetChar (readPort, &ibuf); switch (c) { case 'A': /* UP */ Buffer[wi++] = 0x10;/* ^P */ break; case 'B': /* DOWN */ Buffer[wi++] = 0x0e;/* ^N */ break; case 'C': /* RIGHT */ Buffer[wi++] = 0x06;/* ^F */ break; case 'D': /* LEFT */ Buffer[wi++] = 0x02;/* ^B */ break; case '0': /* F1 */ ConGetChar (readPort, &ibuf); /* discard tilde */ Buffer[wi++] = 0x1b;/* HELP = "ESC ?" */ Buffer[wi++] = '?'; break; case '1': /* F2 or SHIFTED function key */ c = ConGetChar (readPort, &ibuf); /* Get next char to see if it's a tilde */ switch (c) { case '~': /* was definately F2 */ Buffer[wi++] = 0x1b; /* mark-set = "ESC ." */ Buffer[wi++] = '.'; break; case '0': /* SHIFTED F1 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x18; /* binding-for-key = "Ctl-X ?" */ Buffer[wi++] = '?'; break; case '1': /* SHIFTED F2 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x18; /* file-read = "Ctl-X Ctl-R" */ Buffer[wi++] = 0x12; break; case '2': /* SHIFTED F3 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x18; /* file-save = "Ctl-X Ctl-S" */ Buffer[wi++] = 0x13; break; case '3': /* SHIFTED F4 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x18; /* file-visit = "Ctl-X Ctl-V" */ Buffer[wi++] = 0x16; break; case '4': /* SHIFTED F5 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x18; /* file-write = "Ctl-X Ctl-W" */ Buffer[wi++] = 0x17; break; case '5': /* SHIFTED F6 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x18; /* save-all-buffers = "Ctl-X return" */ Buffer[wi++] = '\r'; break; case '6': /* SHIFTED F7 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x18; /* buffer-set-file-name = "Ctl-X Ctl-F" */ Buffer[wi++] = 0x06; break; case '7': /* SHIFTED F8 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x18; /* insert-file = "Ctl-X TAB" */ Buffer[wi++] = '\t'; break; case '8': /* SHIFTED F9 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x18; /* quit-save-all = "Ctl-X Ctl-E" */ Buffer[wi++] = 0x05; break; case '9': /* SHIFTED F10 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x03; /* quit-no-save = "Ctl-C" */ break; } break; case '2': /* F3 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x1b;/* search-forv = "ESC s" */ Buffer[wi++] = 's'; break; case '3': /* F4 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x1b;/* search-again = "ESC t" */ Buffer[wi++] = 't'; break; case '4': /* F5 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x1b;/* replace = "ESC %" */ Buffer[wi++] = '%'; break; case '5': /* F6 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x19;/* yank = "Ctl-Y" */ break; case '6': /* F7 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x1b;/* copy-mark-to-cursor = "ESC w" */ Buffer[wi++] = 'w'; break; case '7': /* F8 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x17;/* delete-mark-to-cursor = "Ctl-W" */ break; case '8': /* F9 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x18;/* move-to-byte = "Ctl-X G" */ Buffer[wi++] = 'G'; break; case '9': /* F10 */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x07;/* abort-cmd = "Ctl-G" */ break; case '?': /* HELP */ ConGetChar (readPort, &ibuf); /* Discard the tilde */ Buffer[wi++] = 0x1b;/* help = "ESC ?" */ Buffer[wi++] = '?'; break; } return Buffer[ri++] & 0x7f; } else /* not an ANSI sequence */ return c & 0x7f; } /* * This function is called once to set up the terminal device streams. * On VMS, it translates TT until it finds the terminal, then assigns * a channel to it and sets it raw. On CPM it is a no-op. */ void ttopen () { int Sig; ULONG conreadsig, windowsig; BYTE error; struct Screen Screen; /* get a copy of WBENCHSCREEN in here */ if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 0))) { printf ("Can't open intuition\n"); ttclose (); exit (10); } /* Create reply port and io block for writing to console */ if (!(writePort = CreatePort ("LARN.console.write", 0))) { printf ("Can't create write port\n"); ttclose (); exit (10); } if (!(writeReq = (struct IOStdReq *) CreateExtIO (writePort, (LONG) sizeof (struct IOStdReq)))) { printf ("Can't create write request\n"); ttclose (); exit (10); } /* Create reply port and io block for reading from console */ if (!(readPort = CreatePort ("LARN.console.read", 0))) { printf ("Can't create read port\n"); ttclose (); exit (10); } if (!(readReq = (struct IOStdReq *) CreateExtIO (readPort, (LONG) sizeof (struct IOStdReq)))) { printf ("Can't create read request\n"); ttclose (); exit (10); } if (!GetScreenData (&Screen, sizeof (struct Screen), WBENCHSCREEN, NULL)) { printf ("Can't get screen size\n"); ttclose (); exit (10); } nrow = Screen.Height / 8 - 3; ncol = Screen.Width / 8; nw.Height = Screen.Height; nw.Width = Screen.Width; /* don't allow a larger number of rows than we can handle */ if (nrow > NROW) nrow = NROW; /* don't allow a larger number of cols than we can handle */ if (ncol > NCOL) ncol = NCOL; /* Open a window */ if (!(win = OpenWindow (&nw))) { printf ("Can't open window\n"); ttclose (); exit (10); } /* Now, attach a console to the window */ if (error = OpenConsole (writeReq, readReq, win)) { printf ("Can't open console.device\n"); ttclose (); exit (10); } else OpenedConsole = TRUE; QueueRead (readReq, &ibuf); /* send the first console read request */ conreadsig = 1 << readPort->mp_SigBit; windowsig = 1 << win->UserPort->mp_SigBit; for (Sig = 0; Sig < NSIG; Sig++) signal (Sig, SIG_IGN); kbdpoll = FALSE; /* on all screens we are not sure of the initial position of the cursor */ ttrow = 999; ttcol = 999; } /* END OF TERMIO REPLACEMENT CODE */ /* Attach console device to an open Intuition window. * This function returns a value of 0 if the console * device opened correctly and a nonzero value (the error * returned from OpenDevice) if there was an error. */ BYTE OpenConsole (writereq, readreq, window) struct IOStdReq *writereq; struct IOStdReq *readreq; struct Window *window; { BYTE error; writereq->io_Data = (APTR) window; writereq->io_Length = sizeof (struct Window); error = OpenDevice ("console.device", 0, writereq, 0); readreq->io_Device = writereq->io_Device; /* clone required parts */ readreq->io_Unit = writereq->io_Unit; return (error); } void CloseConsole (struct IOStdReq *writereq) { CloseDevice (writereq); } /* Output a single character to a specified console */ void ConPutChar (struct IOStdReq *writereq, UBYTE character) { writereq->io_Command = CMD_WRITE; writereq->io_Data = (APTR) & character; writereq->io_Length = 1; DoIO (writereq); /* command works because DoIO blocks until command is done * (otherwise ptr to the character could become invalid) */ } /* Output a stream of known length to a console */ void ConWrite (struct IOStdReq *writereq, UBYTE * string, LONG length) { writereq->io_Command = CMD_WRITE; writereq->io_Data = (APTR) string; writereq->io_Length = length; DoIO (writereq); /* command works because DoIO blocks until command is done * (otherwise ptr to string could become invalid in the meantime) */ } /* Output a NULL-terminated string of characters to a console */ void ConPuts (struct IOStdReq *writereq, UBYTE * string) { writereq->io_Command = CMD_WRITE; writereq->io_Data = (APTR) string; writereq->io_Length = -1; /* means print till terminating null */ DoIO (writereq); } /* Queue up a read request to console, passing it pointer * to a buffer into which it can read the character */ void QueueRead (struct IOStdReq *readreq, UBYTE * whereto) { readreq->io_Command = CMD_READ; readreq->io_Data = (APTR) whereto; readreq->io_Length = 1; SendIO (readreq); } struct IOStdReq *readreq; /* ttkeyready() needs to be able to see this */ /* Wait for a character */ char ConGetChar (struct MsgPort *msgport, UBYTE * whereto) { register temp; WaitPort (msgport); readreq = (struct IOStdReq *) GetMsg (msgport); temp = *whereto; /* get the character */ QueueRead (readreq, whereto); /* then re-use the request block*/ return ((char) temp); } /* typahead(): Check to see if any characters are already in the keyboard buffer On the amiga, we do this by checking if the outstanding read request has been satisfied yet by calling CheckIO(). */ ttkeyready () { if (!kbdqp) kbdqp = CheckIO (readreq) ? 1 : 0; return kbdqp; } /* UNIX support stuff */ #define BLOCKSIZE 4096 link (char *SPath, char *DPath) { int sfd, dfd, Bytes; char BlkBuf[BLOCKSIZE]; if ((sfd = open (SPath, O_RDONLY)) == -1) return -1; if ((dfd = open (DPath, O_WRONLY | O_CREAT | O_TRUNC)) == -1) return -1; while ((Bytes = read (sfd, BlkBuf, BLOCKSIZE)) > 0) write (dfd, BlkBuf, Bytes); close (sfd); close (dfd); return 0; } #endif /* AMIGA */ beav-140/basic.c0000644000175000001440000002705705667134706013512 0ustar samusers00000000000000/* * Basic cursor motion commands. * The routines in this file are the basic * command functions for moving the cursor around on * the screen, setting mark, and swapping dot with * mark. Only moves between lines, which might make the * current buffer framing bad, are hard. */ #include "def.h" bool move_ptr (); bool forwchar (); bool wind_on_dot (); bool backline (); extern char MSG_mark_set[]; extern char MSG_no_mark[]; extern char MSG_go_b_n[]; extern char MSG_bad_num[]; #if RUNCHK extern char ERR_bas_1[]; #endif extern char MSG_lX[]; extern char MSG_lO[]; extern char MSG_lD[]; extern bool rplc_mode; /* pvr * Move cursor backwards. Do the * right thing if the count is less than * 0. Error if you try to move back from * the beginning of the buffer. */ bool backchar (f, n, k) register int f, n, k; { if (n < 0) return (forwchar (f, -n, KRANDOM)); while (n--) { if (curwp->w_unit_offset == 0) { if (!move_ptr (curwp, -(long) R_B_PER_U (curwp), TRUE, TRUE, TRUE)) return (FALSE); /* step to previous unit */ curwp->w_unit_offset = R_CHR_PER_U (curwp) - 1; /* if before first line in window then move window */ wind_on_dot (curwp); } else curwp->w_unit_offset--; } curwp->w_flag |= WFMODE; /* update mode line */ return (TRUE); } /* pvr * Move cursor forwards. Do the * right thing if the count is less than * 0. Error if you try to move forward * from the end of the buffer. */ bool forwchar (f, n, k) register int f, n, k; { if (n < 0) return (backchar (f, -n, KRANDOM)); curwp->w_flag |= WFMODE; /* update mode line */ while (n--) { if (curwp->w_unit_offset >= (R_CHR_PER_U (curwp) - 1)) { /* move to the mext unit */ curwp->w_unit_offset = 0; if (!move_ptr (curwp, (long) R_B_PER_U (curwp), TRUE, TRUE, TRUE)) { /* I am at the the end of the buffer */ return (FALSE); } /* if after the last line in window then move window */ wind_on_dot (curwp); } else if /* if at last byte of buffer then do not step */ (DOT_POS (curwp) < BUF_SIZE (curwp)) curwp->w_unit_offset++; /* step within unit */ } return (TRUE); } /* pvr * This function moves the specified pointer by the ammount specified * in 'len'. Move the dot pointer is 'dot' is true, else move * the window pointer. Do the fix up if 'fix' is TRUE. * This is a relative move if 'rel' is TRUE, else it is an * absolute move. */ bool move_ptr (wp, len, dot, fix, rel) WINDOW *wp; long len; bool dot, fix, rel; { A32 cur_pos, dest_pos, fix_val, last_pos; long rel_pos; A32 last_fixed_pos, align; LINE **line; int *l_off; char shift; bool no_limit; no_limit = TRUE; if (dot) { /* move dot position */ l_off = (int *) &wp->w_doto; line = &wp->w_dotp; align = R_SIZE (wp); /* bytes -1 in a unit */ } else { /* move window position */ l_off = (int *) &wp->w_loff; line = &wp->w_linep; align = R_ALIGN (wp) - 1; /* interval of bytes to align window */ } /* get the current position in the buffer */ cur_pos = (*line)->l_file_offset + *l_off; if (rel) { rel_pos = len; dest_pos = len + cur_pos; /* destination position */ } else { rel_pos = len - cur_pos;/* relative move amount */ dest_pos = len; /* destination position */ } if (fix) { shift = wp->w_disp_shift; /* limit at begining */ if ((long) dest_pos < (long) shift) { rel_pos = shift - cur_pos; no_limit = FALSE; } else { /* calculate fixed up destination position */ fix_val = dest_pos &= ~align; fix_val += shift; /* calculate the last position in the buffer */ last_pos = BUF_SIZE (wp); if (last_pos < (last_fixed_pos = (last_pos & ~align) + shift)) last_pos = last_fixed_pos - align - 1; /* if we are going to limit at the end of the buffer */ if (last_pos < fix_val) { fix_val = last_pos; no_limit = FALSE; } rel_pos = fix_val - cur_pos; } } while (TRUE) { if (rel_pos < 0) /* move backward through buffer */ { /* current line? */ if (*l_off + rel_pos >= 0) { *l_off += (short) rel_pos; return (no_limit); } /* are we at the first line */ if ((*line)->l_bp->l_size != 0) { /* no, so step back */ rel_pos += *l_off; (*line) = (*line)->l_bp; /* move back one line */ *l_off = (*line)->l_used; } else { /* yes, limit at the begining */ *l_off = 0; return (FALSE); } } else /* move forward through buffer */ { /* is in current line? */ if (((A32) (*l_off) + rel_pos) < ((A32) ((*line)->l_used))) { *l_off += (short) rel_pos; return (no_limit); } if ((*line)->l_fp->l_size != 0) { rel_pos -= (*line)->l_used - *l_off; *l_off = 0; (*line) = (*line)->l_fp; /* move forward one line */ } else { *l_off = (*line)->l_used; /* at last line so limit it */ return (FALSE); } } } } /* pvr * Move the window so that the dot is within it's * area. Return TRUE if window was moved. */ bool wind_on_dot (wp) WINDOW *wp; { long diff, incr; A32 d_offs, w_start, bytes, align; /* number of bytes in a row */ bytes = R_BYTES (wp); /* number of bytes to align on */ align = R_ALIGN (wp); /* offset of window from start of the buffer */ w_start = WIND_POS (wp); /* offset of dot from start of the buffer */ d_offs = DOT_POS (wp); /* calculate the amount to move that is 1/3 of the window */ incr = bytes * wp->w_ntrows / 3; /* if dot is before first line in window */ if ((diff = (d_offs - w_start)) < 0) /* diff used later */ { move_ptr (wp, diff - incr, FALSE, TRUE, TRUE); wp->w_flag |= WFHARD; return (TRUE); } /* if dot is after the last line in window */ if (0 < (diff -= (wp->w_ntrows * bytes - 1))) { if (align != 1) diff = (diff & ~(align - 1)) + align; move_ptr (wp, diff + incr, FALSE, TRUE, TRUE); wp->w_flag |= WFHARD; return (TRUE); } /* is window aligned? */ if (w_start != ((w_start & ~(align - 1)) + wp->w_disp_shift)) { /* if no then move into alignment */ move_ptr (wp, 0L, FALSE, TRUE, TRUE); wp->w_flag |= WFHARD; return (TRUE); } return (FALSE); } /* pvr * Go to the beginning of the * buffer. Setting WFHARD is conservative, * but almost always the case. */ bool gotobob () { move_ptr (curwp, 0L, TRUE, TRUE, FALSE); /* move dot */ move_ptr (curwp, 0L, FALSE, TRUE, FALSE); /* move window */ curwp->w_unit_offset = 0; curwp->w_flag |= WFHARD; return (TRUE); } /* pvr * Go to the end of the buffer. * Setting WFHARD is conservative, but * almost always the case. * Dot is one byte past the end of the buffer. */ bool gotoeob () { move_ptr (curwp, BUF_SIZE (curwp), TRUE, TRUE, FALSE); /* move dot */ curwp->w_unit_offset = 0; wind_on_dot (curwp); return (TRUE); } /* pvr * Move forward by full lines. * If the number of lines to move is less * than zero, call the backward line function to * actually do it. The last command controls how * the goal column is set. */ bool forwline (f, n, k) int f, n, k; { if (n < 0) return (backline (f, -n, KRANDOM)); if (rplc_mode) { next_pat (); } else { /* move dot */ if (!move_ptr (curwp, (long) R_BYTES (curwp) * n, TRUE, TRUE, TRUE)) curwp->w_unit_offset = 0; wind_on_dot (curwp); curwp->w_flag |= WFMODE;/* update mode line */ } return (TRUE); } /* pvr * This function is like "forwline", but * goes backwards. The scheme is exactly the same. * Check for arguments that are less than zero and * call your alternate. Figure out the new line and * call "movedot" to perform the motion. */ bool backline (f, n, k) int f, n, k; { if (n < 0) return (forwline (f, -n, KRANDOM)); if (rplc_mode) { next_pat (); } else { if (!move_ptr (curwp, -((long) (R_BYTES (curwp) * n)), TRUE, TRUE, TRUE)) curwp->w_unit_offset = 0; /* is dot before the top of window? */ wind_on_dot (curwp); curwp->w_flag |= WFMODE;/* update mode line */ } return (TRUE); } /* pvr * Scroll forward by a specified number * of lines, or by a full page if no argument. * (KRW) Added cursor (dot) weighting to force cursor * to same position on new page. */ bool forwpage (f, n, k) int f, n, k; { long mov_lines; if (rplc_mode) next_pat (); else { if (curwp->w_ntrows <= 2) mov_lines = 2; else mov_lines = curwp->w_ntrows - 2; /* check if last line is already displayed */ if (WIND_POS (curwp) + (R_BYTES (curwp) * curwp->w_ntrows) < curwp->w_bufp->b_linep->l_bp->l_file_offset + curwp->w_bufp->b_linep->l_bp->l_used) { move_ptr (curwp, (long) (R_BYTES (curwp) * mov_lines), FALSE, TRUE, TRUE); } /* move dot by same amount */ if (!move_ptr (curwp, (long) (R_BYTES (curwp) * mov_lines), TRUE, TRUE, TRUE)) curwp->w_unit_offset = 0; curwp->w_flag |= WFHARD; } return (TRUE); } /* pvr * This command is like "forwpage", * but it goes backwards. */ bool backpage (f, n, k) int f, n, k; { long mov_lines; if (rplc_mode) next_pat (); else { if (curwp->w_ntrows <= 2) mov_lines = 2; else mov_lines = curwp->w_ntrows - 2; /* move window */ move_ptr (curwp, -(long) (R_BYTES (curwp) * mov_lines), FALSE, TRUE, TRUE); /* move dot by same amount */ if (!move_ptr (curwp, -(long) (R_BYTES (curwp) * mov_lines), TRUE, TRUE, TRUE)) curwp->w_unit_offset = 0; curwp->w_flag |= WFHARD; } return (TRUE); } /* * Set the mark in the current window * to the value of dot. A message is written to * the echo line unless we are running in a keyboard * macro, when it would be silly. */ bool setmark () { if (curbp == blistp) /* jam - hack to do goto/kill */ pickone (); else { curwp->w_markp = curwp->w_dotp; curwp->w_marko = curwp->w_doto; if (kbdmop == NULL) { writ_echo (MSG_mark_set); } } return (TRUE); } /* pvr * Swap the values of "dot" and "mark" in * the current window. This is pretty easy, because * all of the hard work gets done by the standard routine * that moves the mark about. The only possible * error is "no mark". */ bool swapmark () { register short odoto; register LINE *odotp; if (curwp->w_markp == NULL) { writ_echo (MSG_no_mark); return (FALSE); } odotp = curwp->w_dotp; curwp->w_dotp = curwp->w_markp; curwp->w_markp = odotp; odoto = curwp->w_doto; curwp->w_doto = curwp->w_marko; curwp->w_marko = odoto; wind_on_dot (curwp); curwp->w_flag |= WFMODE; /* update mode line */ return (TRUE); } /* pvr * Go to a specific byte position in buffer. * If an argument is present, then * it is the byte number, else prompt for a byte number * to use. */ bool gotoline (f, n, k) int f, n, k; { A32 index; register int s; char buf[32]; if (f == FALSE) { if ((s = ereply (MSG_go_b_n, buf, sizeof (buf), 0) != TRUE)) return (s); switch (R_TYPE (curwp)) { case TEXT: case ASCII: case EBCDIC: case BINARY: case HEX: sscanf (buf, MSG_lX, &index); break; case OCTAL: sscanf (buf, MSG_lO, &index); break; case DECIMAL: #if FLOAT_DISP case FLOAT: #endif sscanf (buf, MSG_lD, &index); break; #if RUNCHK default: writ_echo (ERR_bas_1); break; #endif } } if (n <= 0) { writ_echo (MSG_bad_num); return (FALSE); } move_ptr (curwp, index, TRUE, TRUE, FALSE); curwp->w_unit_offset = 0; curwp->w_flag |= WFMODE; /* update mode line */ wind_on_dot (curwp); return (TRUE); } beav-140/beav.def0000644000175000001440000000011605667134706013645 0ustar samusers00000000000000NAME BEAV WINDOWCOMPAT NEWFILES DESCRIPTION 'Binary (file) editor and viewer' beav-140/beav.lnk0000644000175000001440000000033005667134706013671 0ustar samusers00000000000000BASIC +BUFFER +CINFO +DISPLAY +ECHO +EXTEND + EBCDIC + LANGUAGE + FILE +FILEIO +FORMAT +KBD +LINE +MAIN +RANDOM +REGION + SEARCH +SPAWN +SYMBOL +TEXT +TTY +TTYIO +TTYKBD + WINDOW +WORD + WANGPC /STACK:4096 BEAV.EXE; beav-140/beav140.txt0000644000175000001440000026006505667134706014166 0ustar samusers00000000000000 THE BEAV Binary Editor And Viewer Manual Copyright 1992 Version 1.40 April 2, 1993 By Peter Reilley 19 Heritage Circle Hudson, N.H. 03051 pvr@wiis.wang.com BEAV source and executable can be freely distributed for non-commercial purposes. BEAV User Manual 2 1 Introduction 3 1.1 Quick Start 4 2.Overview 5 2.1 Terms and Definitions 5 2.2 The Screen Format 5 2.3 Display Modes 6 2.4 Commands 7 2.5 Buffers 8 2.6 Files 9 2.7 Key Binding 9 2.8 Configuration 10 2.9 International Language Support 10 3.Command Description 11 3.1 Help 11 3.2 Cursor Movement 11 3.3 Buffer Management 13 3.4 File Management 15 3.5 Window Management 16 3.6 Inserting and deleting 18 3.7 Search and Replace Commands 20 3.8 Exiting BEAV 21 3.9 Printing 22 3.10 Keyboard Macros 22 3.11 Key Binding 22 3.12 Special Functions 24 4.Alphabetical list of commands by name 27 5.Alphabetical list of commands by key binding 30 6.Release notes 33 7.Source Availability 37 BEAV User Manual 3 1 Introduction BEAV is an editor that brings the features of a powerful full screen editor to the editing of binary files. It is the only editor that I know of that does that. When you need to edit a non-text file you generally have two choices; a text editor or a file zap type editor. Each choice has significant disadvantages. Text editors expect the file to be formatted in a certain way. At a minimum they expect that all lines be terminated by a carriage return or line feed and be limited in length. There is no line length limit with BEAV. Most text editors get confused by bytes that are outside of the normal range (20 to 7E HEX). In BEAV no special characters such as carriage return or line feed affect the display aside from producing their numeric value. BEAV can edit any file no matter the format. The other choice is to use a file zap type editor which can edit a binary file without difficulty. These editors are often very limited in their features and capabilities. Most file zap programs can edit a file only in HEX or ASCII. They generally operate on a sector basis and because of this they cannot insert or delete data in the middle of the file. All these limits are eliminated in BEAV. You can edit a file in HEX, ASCII, EBCDIC, OCTAL, DECIMAL, and BINARY. You can display but not edit data in FLOAT mode. You can search or search and replace in any of these modes. Data can be displayed in BYTE, WORD, or DOUBLE WORD formats. While displaying WORDS or DOUBLE WORDS the data can be displayed in INTEL's or MOTOROLA's byte swap format. Data of any length can be inserted at any point in the file. The source of this data can be the keyboard, another buffer, of a file. Any data that is being displayed can be sent to a printer in the displayed format. Files that are bigger than memory can be handled. Some users may recognize the similarity to the EMACS text editor that was written by Richard Stallman at MIT. This is not a coincidence. I attempted to keep as much of the user interface and functionality as possible given the very different tasks of EMACS and BEAV. BEAV User Manual 4 1.1 Quick Start This is a brief description of the minimal set of commands that are necessary to start using BEAV effectively. The file-visit command, Ctl-X Ctl-V, can be used to read a file in for editing. The file can also be read in from the command line; beav . These commands can be used to navigate around the window. move-back-char Ctl-B moves left move-back-line Ctl-P moves up move-forw-char Ctl-F moves right move-forw-line Ctl-N moves down The move-to-byte command, Ctl-X G, will prompt you for a byte position to move to. These commands will insert a zero byte at the cursor position or delete the byte at that position. insert-unit Ctl-X I delete-forw-unit Esc D The file-save command, Ctl-X Ctl-S, will save the data to the file if a change has been made. The help command, Esc ?, will display a list of all commands and their current key bindings. The abort-cmd command, Ctl-G, will abort any command that is in operation. The quit-no-save command, Ctl-X Ctl-C, will exit BEAV. If there is any data that has not been saved you will be warned. BEAV User Manual 5 2. Overview 2.1 Terms and Definitions Throughout this manual certain terms will be used to describe the operation and structure of BEAV. The data that BEAV is editing is held in a buffer that is structured as a byte stream. There are many commands that affect the way that this byte stream is displayed on to the screen. Whatever display mode is chosen the data in the buffer is not effected, only the presentation. One such choice is to display the data as bytes, words, or double words. That is; 8 bit values, 16 bit values, or 32 bit values. Whatever choice is made the value of the selected size will be displayed. These values are referred to as units in this manual. Thus the 'delete-forw-unit' command deletes the unit under the cursor. If 32 bit units are being displayed then 4 bytes will be deleted. Many commands in BEAV start by pressing the 'ESCAPE' key. When this manual refers to a command that requires that the 'ESCAPE' key be pressed it will be abbreviated with 'Esc'. Another frequently used key stroke to start commands is 'CONTROL X'. This in done by pressing the 'CONTROL' key then pressing the 'X' key at the same time. In this manual this will be abbreviated by 'Ctl-X'. Many commands contain other control characters and these will be abbreviates similarly. Thus the 'insert-unit' command will be listed as 'Ctl-X I'. This will be entered be pressing the CONTROL key and while holding it hitting the 'X' key, release the CONTROL key then hit the 'I' key. 2.2 The Screen Format BEAV presents information to the user in a number of areas. The first is the window. There will be at least one window displayed on the screen at all times. The window consists of two areas. The first is the display area. This is where the data that is in the buffer is displayed. Most of the time the cursor will be in this area, as this is where most editing is done. Each line in the display area will start with a number that indicates the offset into the buffer for this line of data. At the bottom of the display area for each window is the status line. The status line presents the user with a number of specific pieces of information. The first is the program name which is "BEAV". Next there are some flags indicating the status of this particular buffer. BEAV User Manual 6 The first flag indicates if the buffer has been damaged by a memory allocation failure. If there is a '?' then the buffer is bad, otherwise there will be a space. Bad buffers are set to read only. The next flag indicates if the buffer has been changed and will need to be written out if the changes are to be saved. This flag is a '*' if the buffer has been changed, otherwise there will be a space. The next flag indicates insert/overstrike mode; 'I' for insert, 'O' for overstrike. This is only meaningful in ascii or ebcdic mode. Then the buffer name followed by the file name. A window can be in read only, read/write, or read/write with size lock. These will be displayed as [RO], [RW], or [WL] respectively. If auto-update is enabled then [AU] will be displayed. Next the cursor position in bytes and the character position within the unit. The next piece of information gives the format that the data is being displayed in; HEX, OCTAL, DECIMAL, FLOAT, BINARY, ASCII, EBCDIC. If a data mode is selected then the size in bytes (1, 2, 4) is displayed. If the data is being displayed in Intel mode then the swapped flag is displayed, 'S'. Lastly the byte shift is displayed; 0 only for 8 bit data, 0 or 1 for 16 bit data, or 0, 1, 2 or 3 for 32 bit data. There can be multiple windows on the screen at the same time but each window will have a status line at the bottom. The very bottom line on the screen is the prompt line. This is where you enter data that BEAV requests. If you want to edit a new file you would type 'Ctl-X Ctl-V', BEAV would respond with "Visit file:" on the prompt line. The cursor would be positioned after the prompt. You would then enter the name of the file that you wished to edit. If you entered the command by mistake, you can abort the operation by typing a 'Ctl-G'. 'Control G' is a universal abort command and can be used anywhere. If you want to perform a search you will enter the search string on this line. When you have entered the information that BEAV has requested hit 'Return' and the cursor will return to it's original position in the window display area. The prompt line is also where error messages are displayed. 2.3 Display Modes The data in the buffer can be displayed in a number of formats. First there is the display mode. This can be either; HEXADECIMAL, DECIMAL, OCTAL, BINARY, FLOAT, ASCII, or EBCDIC. BEAV User Manual 7 If ASCII or EBCDIC mode is chosen then each byte in the buffer will be converted to it's ASCII or EBCDIC character and displayed. Bytes that are outside of the standard character set will be displayed as a dot. Each line will be 64 characters long. The byte value for "carriage return" and "line feed" will be displayed as a dot as will any other non-printable characters. Within HEXADECIMAL, DECIMAL, OCTAL, or BINARY format the data can be displayed in 8, 16 or 32 bit values. If 16 or 32 it values are displayed the user can choose to view these values in either the Intel format or the Motorola format. If Intel format is chosen then the first byte in each unit is the least significant byte when the value is calculated. Thus in hex 32 bit mode a byte string of "32 7A 9F 10" would be displayed as "109F7A32". If Motorola format is chosen this value would be displayed as "327A9F10". The FLOAT mode displays the data in floating point representation. This is somewhat machine dependent so a given hex number may produce different floating point numbers on different machines. Generally, not all combinations of bits are legal floating point numbers. The display representation will depend on how printf was implemented. It is conceivable that BEAV will crash if the printf function is not robust. There is another display format choice that affects the 16, 32 or 64 bit formats. This is called shift. The shift can be 0 or 1 for 16 bit modes, 0, 1, 2, or 3 for 32 bit modes, or between 0 - 7 for floating point mode. Shift moves the zero point reference for the buffer up by the selected value. The default is zero shift. If a buffer is displaying the following 32 bit hex data; "12345678 2F4792AF 673DFEA1 88551199" with the shift at 0. Changing shift to 1 will produce; "3456782F 4792AF67 3DFEA188 55119955" The data has been slid down toward the beginning of the buffer by one byte. This has not changed the data in the buffer at all, it has only affected the way that the data is presented on the screen. This is useful when looking at WORD or DOUBLE WORD data that is not aligned on two or four byte boundaries. When BEAV is first started or a new window is opened the default format is HEXADECIMAL BYTES. 2.4 Commands BEAV User Manual 8 Commands are the means that the user controls the operation of BEAV. A command can be given by using one of two methods. The first is to use the key binding. A command can have one or more associated key bindings. It can also have no key binding. There are a set of default key bindings that BEAV comes configured with. The current set of key bindings can be seen by using the 'help' command. The 'help' command is 'Esc ?' or Function Key 1 'F1' on the IBM PC. The help buffer can be scrolled by using the up and down arrow keys. A printed copy may be obtained by going to the bottom of the help buffer using the 'move-to-end' command ('Esc >' or the 'End' key). Then issue the 'print-mark-to-cursor' command ('Esc P' or 'Ctl-Print') and enter 'PRN' or a file name when prompted with "Print to:". This will output the entire help buffer to a printer connected to the parallel interface or the specified file. The second method of issuing a command is to use the 'extended-command' command (Esc X). You are prompted for a command name that you want to execute. This method is useful for executing commands that have no key binding. Commands that can take a long time to complete can be stopped by pressing Ctl- G. 2.5 Buffers Buffers are the in memory storage for all data editing and viewing. Each buffer has a name that appears in the mode line. Buffers generally have a file name that is associated with them. The file name also appears in the mode line. The buffer name and the file name are independent but the buffer name defaults to the file name. The buffer name is used to refer to a specific buffer. The 'change-buffer' ('Ctl-X B') command will prompt you for a buffer name. After you enter a buffer name that buffer will be displayed in the current window. If there is no such buffer, one will be created and displayed (it will be empty). When BEAV is run with a file name as a command line parameter, the file is read into a new buffer. The buffer name will be made the same as the file name. The file name is only used when the buffer is saved. If the file name is changed using the 'buffer-set-file-name' ('Ctl-X Ctl-F') command then when the buffer is saved it will be saved to the new file. Buffers are dynamically allocated. They grow or shrink as the size of the data they contain changes. The buffer size can be frozen using the 'buffer-size-lock' ('Ctl-X Ctl-L') command. This prevents inserting or deleting data from the buffer but data can be modified. BEAV User Manual 9 Buffers continue to exist even if they are not being displayed. Buffers are saved in a linked list that can be stepped through using the 'change-to-next-buffer' ('Esc +') or 'change-to-prev-buffer' ('Esc -') commands. If the 'change-to- next-buffer' command is given then the next buffer in the list is displayed in the current window. 2.6 Files Files are the means of storing data on disk. Files or segments of files can be loaded into BEAV for editing or viewing. The file on the disk has not been changed until BEAV does a save to that file. When a save to a file is performed the original file contents in saved in a ".bak" file. 2.7 Key Binding All commands in BEAV have a command name and a default key binding. The bindings may be changed to suit personal preference by using the 'bind-to-key' ('Esc K') command. The current binding of a key sequence can be displayed by using the 'binding-for-key' ('Ctl-X ?') command. Key bindings can be loaded automatically from a file named ".beavrc" under UNIX or "beavrc" under MSDOS. I will refer to this file as the beavrc file in this document. This file must be in a directory specified by the PATH environment variable. When BEAV is started this file is read and the bindings are loaded. This file is a simple text file and can be edited to make changes. The beavrc file contains three columns. The first is the function name to be bound or "extended-command" for commands to be executed. For functions to be bound, the second column is the key sequence that is bound to that function. The third is a number that defines the key code. The second column is not actually used, but is for informational purposes only. For commands to be executed, the second column is the command name. The third column is optional and is the number to be passed to that command. For example; to set the number of screen rows to 10 hex (16 decimal); the first column would contain "extended-command", the second column would contain "screen-rows", and the third would contain "10" to set 16 decimal screen rows. BEAV User Manual 10 The simplest way to create a valid beavrc file is to first bind the key codes to the desired functions using the 'bind-to- key' command (Esc K). Next display the current bindings in a window using the 'help' command (Esc ?). Then save that buffer to a file with the 'file-write' command (Ctl-X Ctl-W). You will be prompted for a file name. The file written is a valid beavrc file. You may want to edit the beavrc file to remove the commented lines, ie, those beginning with #, to make it load faster. On UNIX systems there can be multiple .beavrc files, one for each terminal type. This is accomplished by appending the TERM variable to .beavrc. Thus if you use both a vt100 and a wyse60 terminal, you could have a .beavrc.wy60 and a .beavrc.vt100 bindings file. When your TERM variable is TERM=wy60 then the .beavrc.wy60 bindings file will be used. If there is no .beavrc.wy60 file then the .beavrc file will be used. 2.8 Configuration When the MSDOS version of BEAV runs it detects whether the system is an IBM PC or a clone. If a PC is detected then a set of key bindings that use the 10 function keys and the relevant keypad keys are loaded. If the system is not recognized then only the standard bindings are loaded. If a PC is detected the screen is managed by making BIOS level calls that enhance performance. Otherwise, the screen is controlled by making ANSI compatible calls to the operating system. This is much slower but is not sensitive to hardware configuration. This requires that non-standard MSDOS systems support ANSI display controls. The following ANSI escape sequences are used; Position cursor ESC [ ; H Erase to end of line ESC [ 0 K Erase to end of page ESC [ 0 J Normal video ESC [ 0 m Reverse video ESC [ 7 m On unix systems the termcap library is used. This requires that the TERM environment variable be set correctly. 2.9 International Language Support The text strings in BEAV that are language dependent are contained in a seperate file. The text file for the English BEAV User Manual 11 language is names "english.c". Other language files might be named "french.c" or "spanish.c". To change the language of BEAV, rename the desired language file to "language.c". This is the file that will be compiled and linked into BEAV. 3. Command Description This section describes all BEAV commands as to their function and any side effects that they may have. The first line of each description of a command will begin with the default key binding then the command name and follows with the key binding for a PC. 3.1 Help This command returns information that will aid in the use of BEAV. Esc ? help F1 A new window is opened by splitting the current window then all current key bindings are displayed. This buffer is larger than can be shown at one time and must be scrolled up and down to see all entries. All commands that do not alter data can be used to move around and search the help buffer. To leave the help buffer use the 'window-delete' command ('Ctl-X 0'). Lines that begin with the comment character (#) are commands that have the default bindings. Lines without the comment character have been bound by the user or by processing a beavrc file. The comment character helps in creating a beavrc file by identifying only those bindings that have changed. 3.2 Cursor Movement There are a number of commands that move the cursor around the current window. If the cursor bumps the top or the bottom of the window the position of the window will be adjusted so as to keep the cursor within the bounds. When the window is moved in response to cursor movements it is moved by about one third of the window size. This improves performance by reducing the number of window moves. Ctl-P move-back-line North (up arrow) Ctl-N move-forw-line South (down arrow) These commands move the cursor up one line or down one line. If the cursor is on the top line in the buffer and a BEAV User Manual 12 'move-back-line' command is given the cursor will jump to the beginning of the first unit in the buffer. If the cursor is on the last line of the buffer and a 'move-forw-line' is given the cursor will move to the last unit in the buffer. Ctl-F move-forw-char East (right arrow) Ctl-B Move-back-char West (left arrow) These commands move the cursor forward or backward in the current line. If the cursor is at the first character in the first unit of the line and the 'move-back-char' command is given then the cursor will wrap to the last character of the previous line. If the cursor is at the last character of the last unit in the current line then it will wrap to the first character of the next line. Esc F move-forw-unit Ctl-East Esc B move-back-unit Ctl-West These commands are similar to the above set but they move the cursor by units rather than characters. The command 'move- forw-unit' will position the cursor to the first character of the next unit. The command 'move-back-unit' will move the cursor to the first character of the previous unit. Ctl-V move-forw-page PageUp Esc V move-back-page PageDown These commands move the move the data in the window by the number of lines in the window less one. The cursor will stay in the same position relative to the window as the data is moved. Esc < move-to-beginning Home Esc > move-to-end End Move the cursor to the beginning or the end of the buffer. Ctl-X G move-to-byte F9 Prompt for a byte offset, then go to that position in the current buffer. Ctl-X Ctl-N move-window-down Ctl-Z Ctl-X Ctl-P move-window-up Esc Z Move the buffer in the window up or down by one line. This does not effect the cursor until it hits the top or bottom of the window. Esc . mark-set F2 Set the mark position to the current cursor position. The mark position is remembered even for nonactive windows and buffers. BEAV User Manual 13 Ctl-X Ctl-X swap-cursor-and-mark The position of the cursor and the position of the mark are swapped. Esc L window-link This command causes all windows that are displaying the contents of the current buffer to have the same cursor position. Thus if one window is scrolled then all other windows that display that buffer are scrolled so as to keep the cursor in the window. Ctl-X = show-position The current position of the cursor and the mark are displayed. The buffer size, file size and file name are also shown. 3.3 Buffer Management Buffers store all data that is being edited. The only limit to the number of buffers is the size of available memory. If a file is loaded into a buffer and there is insufficient memory to hold the entire file, then it will be loaded until memory is exhausted. The buffer will then be set to read only mode. Ctl-X Ctl-B buffers-display Ctl-F1 A new window is opened and a list of all buffers in BEAV is displayed. The list contains the buffer name, the file name (if it exists), the buffer size, and a state flag. If the list is too large for the window, you can scroll the list. If you position the cursor on a line describing a buffer and give the set-mark (Esc .) command you will be prompted to; Go to, Kill, or Save that buffer. Ctl-X B change-buffer Ctl-F2 This command prompts you for a buffer name. If you enter the name of an existing buffer, that buffer will be displayed in the current window. If the name does not match an existing buffer, a new buffer will be created and displayed. This buffer will be empty and will have no file name. Esc + change-to-next-buffer Ctl-F4 Esc - change-to-prev-buffer Ctl-F5 BEAV User Manual 14 The next or the previous buffer in the buffer list is displayed in the current window. This does not effect buffers that are displayed in other windows. Esc G move-to-buffer-split Prompt for a buffer name. Then split the current window and display that buffer, creating it if necessary. Esc Ctl-N buffer-set-name Esc Ctl-N The current buffer name is changed to the name that you enter. This does not effect the file name. Ctl-X Ctl-F buffer-set-file-name Ctl-F7 The file name of the current buffer is changed to the name that you enter. This does not affect the buffer name. Ctl-X K kill-buffer Ctl-F3 This command prompts you for a buffer name. This buffer is then deleted. If the buffer is currently being displayed you are prompted for conformation. If the buffer has been changed you are again prompted for conformation. Ctl-X Ctl-L buffer-size-lock The buffer size is prevented from being changed. Data can be edited but only by changing the existing data. If a buffer is copied into a size-locked buffer the operation well be successful but will overwrite existing data. This command toggles between locked and unlocked. Esc Y yank-buffer Ctl-F6 Data from one buffer is inserted into the current buffer at the cursor position. You are prompted for the name of the buffer to copy from. Esc O save-mark-to-cursor Prompt for a buffer name. Create a new buffer with that name and write the data from the mark to the cursor into that buffer. Esc Ctl-W show-save-buf Displays the contents of the save buffer in a new window. The save buffer cannot be edited. This command can be used to see the data that the yank (Ctl-Y) command will insert into the current buffer. BEAV User Manual 15 3.4 File Management These commands control BEAV's access to files. Files are loaded into buffers or are written from buffers. Commands that prompt for a file name also accept range parameters. Range parameters are always given in the numeric base of the current window. Thus if you are displaying data in decimal format then the range parameters must be entered in decimal. The size of a file read or write can be limited by specifying a range. The range parameter specifies the offset into the file, not the buffer. Range parameters can be specified in these forms; + The first form causes the read or write to begin from the value until the end of the buffer on write or the end of the file on read. The second form reads or writes from until non-inclusive. The third form reads or writes from for bytes. Thus, if the command 'file-read' is given and you enter at the prompt; main.obj 1000 +100. If the current display mode is hex, the file "main.obj" will be read from hex byte address 1000 to 10FF into the buffer. Ctl-X Ctl-R file-read Sh-F2 Prompt for a file name and read that file into the current buffer. This overwrites the current contents of the buffer. The buffer name is not changed but the buffer file name is set to the new file name. Ctl-X Ctl-S file-save Sh-F3 Write the current buffer out to the file if it has been changed. If the buffer has not been changed then do nothing. Ctl-X V file-view Prompt for a file name and read file into a new buffer and display in current window. Set to read-only mode. Ctl-X Ctl-V file-visit Sh-F4 BEAV User Manual 16 Prompt for a file name. If the buffer already exists then display it in the current window. Otherwise, read file into a new buffer and display in current window. If there is no such file then create it. Esc U file-visit-split Same as above but split current window and display new buffer. This displays the new buffer as well as the old buffer. Ctl-X Ctl-W file-write Sh-F5 Prompt for a file name, then write the current buffer to that file. Ctl-X Tab insert-file Sh-F8 Prompt for a file name and insert that file into the current buffer at the cursor position. Ctl-X Return save-all-buffers Sh-F6 Write all buffers that have been changed to their respective files. 3.5 Window Management BEAV presents information to the user in one or more windows. Each window is a view into a buffer where the data is actually stored. The window controls how this data is formatted for display to the user. Data can be displayed as HEX bytes, OCTAL bytes, ASCII characters, plus many others. The display format is associated with the window. Thus if a new buffer is displayed in the current window that new data will be displayed in the current windows format. The only limit to the number of windows is the screen size. A window can be no smaller than two lines. This along with the mode line associated with each window limits to eight the number of windows on an IBM PC 25 line screen. Any window can view any buffer including having many windows on the same buffer. For example, two windows can display the same buffer but present the data in two different modes. One window could display HEX bytes and the other could display ASCII characters. Ctl-P change-window-back Ctl-PageUp Ctl-N change-window-forw Ctl-PageDown These commands move the cursor to the next or previous window on the screen, making it the current window. BEAV User Manual 17 Ctl-X Z window-enlarge Ctl-X Ctl-Z window-shrink Enlarge or shrink the current window size by one line. Esc ! window-reposition Move window position so that the cursor is centered in the window. The cursor position in the buffer does not change. Ctl-X 2 window-split Split the current window into equal parts. Both halves have the same display mode and view the save buffer. Ctl-X 1 window-single Expand the current window to fill the entire display, all other windows are removed. Make the current window the only window displayed. This has no effect on the underlying buffers except that they may not be displayed any more. Ctl-X 0 window-delete Delete the current window and expand the upper window to fill the space. This has no effect on the underlying buffer except that it may not be displayed any more. Esc Ctl-A display-ascii Esc Ctl-E display-ebcdic Esc Ctl-F display-float Esc Ctl-H display-hex Esc Ctl-O display-octal Esc Ctl-D display-decimal Esc Ctl-B display-binary These commands set the window display mode. Text buffers can be displayed as ASCII or EBCDIC characters. Buffers that are not human readable can also be displayed in hexadecimal, octal, decimal, float, or binary format. Esc 1 display-bytes Esc 2 display-words Esc 4 display-double-words As a further option on the non-text display modes, data can be displayed as 8, 16, or 32 bit values. Floating point numbers are assumed to be 64 bit values. Ctl-E display-swap-order When data is displayed as words or double words the order of significance can be changed. In Intel microprocessors the BEAV User Manual 18 least significant byte of a word is stored at the lowest address. Thus if the word 5892 (HEX) were stored at memory address 10, then 92 (HEX) would be stored at address 10 and 58 (HEX) would be stored at address 11. In Motorola microprocessors the reverse is true. This command toggles between the Intel and Motorola schemes of assembling bytes into words and double words. This command has no effect on byte display or on the text display modes. The data in the buffer is not changed. Ctl-A display-byte-shift This command changes the offset from the beginning of the buffer used to assemble words and double words. The default shift is 0. For example, a double word at address 10 is made up of the bytes at address 10, 11, 12, and 13. With a shift of 1 that double word would be made of bytes 11, 12, 13, and 14. With a shift of 2 then bytes 12, 13, 14, and 15 would be used. The maximum shift in word display mode is one and the maximum shift in double word mode is three. The buffer is in effect shifted toward the beginning of the buffer with 1, 2, or up to 7 bytes becoming not visible. These bytes are not lost, they become visible when the shift is set to zero. This command cycles through all possible shift values. There is no effect in any byte display mode or any text display mode. 3.6 Inserting and deleting These commands are the core of BEAV. These commands allow the buffer to be edited in a similar fashion to a text editor. BEAV has an insert mode much the same as text editors but it only works when displaying data in one of the text modes, either ASCII or EBCDIC. In other modes it doesn't make any sense to insert characters as they are typed when there is more than one characters per unit. In the data modes there is a command that inserts a unit of zeros into the buffer. Similarly the delete commands always delete a unit rather than a character. In a text mode the delete commands work as in a text editor because a unit is a character. Ctl-X I insert-unit Insert a zero at the cursor position. The rest of the data moves down one place. Thus, if double words are being displayed, four bytes are inserted before the cursor position. These bytes are initialized to zero. This command works in all display modes. Ctl-X Ctl-A insert-toggle Insert BEAV User Manual 19 In either of the two text modes this command toggles between insert mode and overwrite mode. In insert mode each character that is typed is inserted in front of the cursor and the rest of the buffer is moved down. In overwrite mode the typed characters replace the character that is at the cursor. This command has no effect in a non-text display mode. Ctl-Q insert-literally Esc Q This command sets a special temporary mode where the next typed character is inserted in the buffer no matter what the character is. This allows control codes to be inserted in the buffer when in a text display mode. Alternatively the same byte could be inserted into the buffer by using one of the data display modes. It night be faster to use this command on some occasions. Ctl-T unit-twiddle The unit at the cursor is swapped with the previous unit. Rubout delete-back-char Backspace This command deletes the character before the cursor and pulls the rest of the buffer back. The cursor remains on the same character as it moves back. It only works in the text and byte display modes. Ctl-D delete-forw-char Delete The character at the cursor is deleted and the buffer is pulled back. The cursor remains at the same position. It only works in the text and byte display modes. Esc Rubout delete-back-unit Esc Ctl-K This command deletes the unit before the cursor and pulls the rest of the buffer back. The cursor remains on the same unit as it moves back. Esc D delete-forw-unit The unit at the cursor is deleted and the buffer is pulled back. The cursor remains at the same position. Esc W copy-mark-to-cursor F7 The area in the buffer from the mark to the current cursor position is copied into the kill buffer. If the mark is not set before this command is given an error is reported. Ctl-W delete-mark-to-cursor F8 BEAV User Manual 20 The area in the buffer from the mark to the current cursor position is deleted and placed into the kill buffer. If the mark is not set before this command is given an error is reported. Ctl-Y yank F6 The contents of the kill buffer is inserted into the buffer at the cursor position. The kill buffer itself is not changed. 3.7 Search and Replace Commands BEAV has very powerful search and replace commands. The search and replace string can be entered in any of the display modes. The search and replace strings can each be up to 256 bytes long. The display mode can be changed at any time while entering the string. Wild cards can be placed down to the bit level on both the search and replace strings. The wild card character, '?', will match any value that it is compared with. When a wild card is placed in the replace string it leaves the destination data unchanged at that position. Thus, if the destination contains the ASCII string '41 42 43 44' and the replace string contains '66 67 ?? 69' the result would be '66 67 43 69'. Wild cards can be placed in any position that makes sense. If you want to use wild cards in an ASCII string then you must switch to another mode to enter them. You can then switch back to ASCII mode. In this case a '?' will appear in the position where the wild card has been placed but it appears exactly the same as a standard question mark. In fact if you type a '?' over the wild card there will be no apparent change. However, the character will no longer be a wild card but a standard question mark. To see the true wild cards you must use a data display mode. In fact if the wild card has been set on the bit level then you must go to binary display mode to see its actual position. The commands to change the display mode in search and replace are the same as for the window display mode. The search and replace strings can be scrolled back an forth and the cursor moved using the same commands as for the window. While performing a replace command you can switch between the search string and replace string by using the 'move-back-page' or 'move- forw-page' commands. Esc S search-forw F3 Prompts for a search string then searches from the current cursor position for the first match. The cursor is positioned at the first unit of the match. BEAV User Manual 21 Esc R search-back This command is the same as the previous one except that it searches backward. Esc T search-again F4 This command repeats the previous search command, forward or backward. The cursor is first moved one byte in the appropriate direction before the search is repeated. Esc % replace F5 Prompt for search string. After entering the search string hit return and you will be prompted for the replace string. After entering the replace string hit return. BEAV will then search for the first match with the search string. If a match is found you will be prompted with '(R)eplace, (S)kip, (A)ll, (O)ne, (Q)uit' If you type a 'R' the replace will be done at this location and the search will continue. If you type a 'S' the replace will not be done and search will continue. If you type an 'A' the replace will be done and will be done at all future matches without pausing for conformation. If you type an 'O' the replace will be done at this location and the search will stop. If you type a 'Q' then the search will be terminated. Ctl-R recall-srch-string If you enter search or replace previously used strings can be recalled with this command. 3.8 Exiting BEAV While using BEAV individual buffers may be saved to disk during the editing session. When quitting BEAV you must save all buffers or delete all buffers. There are two commands that do this. Ctl-C quit-no-save Sh-F10 If there are any unsaved buffers you will be prompted for conformation before proceeding. All buffers will be deleted then you will return to DOS. Ctl-X Ctl-E quit-save-all Sh-F9 All buffers are saved before exiting to DOS. BEAV User Manual 22 3.9 Printing The data that is being displayed in BEAV can be printed or sent to a file in the same format as displayed. If the current window is displaying octal words and a print command is given the format of the print will be in the format of the window; that is, octal words. Esc P print-mark-to-cursor Ctl-Print To use this command you must set the mark and the cursor to define the region that you want printed. If the mark is not set it as assumed to be at the first unit. After you enter the command you will be prompted with 'Print to:'. You can enter a file name or a device name to send the print image to. If you enter 'PRN' most systems will print a hard copy. This is useful for getting a print out of the current key bindings. To do this give the 'help' command 'F1'. Go to the bottom of the help window using the 'move-to-end' command 'End', the mark will be assumed to be at the beginning of the buffer. Issue the 'print-mark-to-cursor' command. Enter 'PRN' at the prompt. This should print the complete help buffer and will reflect any changes that you have made to the key bindings. 3.10 Keyboard Macros BEAV has the capability of recording key strokes as they are entered and playing them back later. This is useful for repeating multi-keystroke operations. Ctl-X ( macro-start Start recording key strokes. There is no effect on the operation of the key strokes. Any previous recorded key strokes are cleared. Ctl-X ) macro-end Stop recording key strokes. The key strokes are available for play back. Ctl-X E macro-execute Play back the recorded key strokes. The key strokes that were recorded are played back as if they were typed at the keyboard. 3.11 Key Binding BEAV User Manual 23 BEAV provides a user configurable interface. The interface is controlled by a set of key bindings. This relates the command that will be executed when a particular key stroke is entered. There are a set of default key bindings as described in this manual. These can be changed to reflect your preferences. When a change is made it is reflected in the help screen. Ctl-X ? binding-for-key Sh-F1 This command will tell you what function a certain key sequence is bound to. When this command is given you will be prompted for a key stroke or key stroke sequence. BEAV will report back with the function name. Esc K bind-to-key First you will prompted for a function name. Enter the name of the function that you wish to create a new binding for. Function names are the names listed in this manual that are of the form of 'move-forw-unit' or 'display-hex'. After you enter the name hit return. You will be prompted for a key. This can be in the form of a single standard key such as 'Z'. Standard key sequences can be entered such as 'Ctl-X Z' or 'Esc Z'. Special keys can be entered such as 'F1' (function key 1) or 'Page Down'. It is probably a good idea to not use keys that are needed for editing. If you bound 'Z' to a function then you would not be able to enter it as a keystroke when using ASCII display mode. You could still enter it using the 'insert-literally' command or doing it in one of the data display modes but this would be more cumbersome. Ctl-X L bindings-load You are prompted for a file name that contains the key binding that you wish to set. This file is read in and the appropriate bindings are set. The text in the binding file should be of the form; For example; Ctl-X Ctl-P move-back-char 0550 F1 move-forw-char 04bb Ctl-A move-forw-unit 0141 Esc Ctl-T move-back-unit 0354 The easiest way of producing a valid key binding file is to set the desired bindings in BEAV. Next issue the 'help' command (ESC ?), then write the buffer out with the file-write command (Ctl-X Ctl-W). The file created will be a valid format for loading and can be edited as desired. It is the only reliable way to get the number. BEAV User Manual 24 3.12 Special Functions These are the commands that do not logically fit under one of the previous headings Ctl-G abort-cmd F10 This command aborts the current command. It can even abort a partially entered command. Thus, if you have typed an 'Esc' as that start of a command you can type Ctl-G to return to the normal command entry mode. Esc A auto-save BEAV can be set to automatically save the current buffer after a specified number of buffer editing commands are given. This command first prompts for the number of operations before the save is made. If a zero is entered at the prompt, this feature is disabled. The default condition of this command is disabled. Esc C compare This is a powerful feature of BEAV. The contents of two windows are compared byte for byte from the current cursor position in each window. There must be exactly two windows to use this command. These windows can be displaying the same or different buffers. When a difference is found the cursor in each window is moved to that position and both windows are moved accordingly. The display mode does not affect the operation of this command except in restricting the cursor position to whole units. Esc X extended-command If any command looses its binding, this command allows the unbound command to be used. A command can loose its binding because the binding was assigned to another command. When this command is given you will be prompted for a command name. Enter the command name that you wish to execute, it will be executed as if you had typed its key binding. Esc Ctl-P n-way-combine The contents of other windows can be copied sequentially into the current window. This is useful in combining odd-even proms into an executable image file. To use this command create an empty window with a buffer file name of an empty or nonexistent file. Read into additional windows the files that you want to combine. While in the empty target window, issue the n-way-combine command. The data in the other windows will BEAV User Manual 25 be read into the current window. The next window lower on the screen will be read first, then the one below that, etc. For example; if you had two files, promlow.bin and promhi.bin that you wanted to combine into a file called prom.bin. First issue the file-visit command (Ctl-X Ctl-V), enter prom.bin at the prompt. This file should be empty of non- existent. Next read promlow.bin into a new window with the file-visit-split command (Esc U), enter promlow.bin at the prompt. Open another window for promhi.bin with the same command. Go to the window containing prom.bin (empty). Issue the n-way-combine command. BEAV will copy the first byte from the window immediately below the prom.bin window and deposit it in the destination window buffer as well as advance the dot position in both windows. It will advance to the next lower window and copy a byte from there into the destination window and advance the dot in both windows. This process will continue until one of the source buffers is exhausted, or the user terminates the command. The user must take care that the source buffers are in the correct order. They are read starting at the window immediately below the current window. If the target window is at the bottom of the screen then it wraps to the top. In this way any order can be used and changed at will. Esc Ctl-S n-way-split This command is the mirror image of the n-way-combine. The data in the current window is distributed among the rest of the window buffers displayed. The current window buffer must be the only window buffer that contains data. If there are two other empty window buffers then the data will be divided two ways. If there are five then the data will be divided five ways Ctl-L refresh-screen The screen is reprinted from BEAV's internal buffer. This is useful if the display is messed up due to transmission errors. On a PC this is unlikely to happen. Esc Ctl-V show-version The version and date of BEAV is displayed in the command line. Ctl-X C spawn-shell A new MSDOS command shell is created. You can return to BEAV by typing 'exit'. Ctl-U repeat count BEAV User Manual 26 This command prompts for a number to be entered. This causes the next command given to be repeated by that number of times. This command cannot have it's binding changed and cannot be issued using the 'extended-command' function. Esc Ctl-R screen-rows The number of rows that beav will use to paint the screen can be set with this command. This command can be given any time, the displayed windows will be adjusted or killed as needed. BEAV User Manual 27 4. Alphabetical list of commands by name Command Key Binding Manual Section ------- ----------- -------------- abort-cmd Ctl-G 3.12 abort-cmd Ctl-X Ctl-G 3.12 abort-cmd Esc Ctl-G 3.12 abort-cmd F10 3.12 auto-save Esc A 3.12 bind-to-key Esc K 3.11 binding-for-key Ctl-X ? 3.11 binding-for-key Sh-F1 3.11 bindings-load Ctl-X L 3.11 buffer-set-file-name Ctl-F7 3.3 buffer-set-file-name Ctl-X Ctl-F 3.3 buffer-set-file-name Sh-F7 3.3 buffer-set-name Esc Ctl-N 3.3 buffer-size-lock Ctl-X Ctl-L 3.3 buffers-display Ctl-F1 3.3 buffers-display Ctl-X Ctl-B 3.3 change-buffer Ctl-F2 3.3 change-buffer Ctl-X B 3.3 change-to-next-buffer Ctl-F4 3.3 change-to-next-buffer Esc + 3.3 change-to-prev-buffer Ctl-F5 3.3 change-to-prev-buffer Esc - 3.3 change-window-back Ctl-PageUp 3.5 change-window-back Ctl-X P 3.5 change-window-forw Ctl-PageDown 3.5 change-window-forw Ctl-X N 3.5 compare Esc C 3.12 copy-mark-to-cursor Esc W 3.6 copy-mark-to-cursor F7 3.6 delete-back-char Backspace 3.6 delete-back-char Rubout 3.6 delete-back-unit Esc Ctl-K 3.6 delete-back-unit Esc Rubout 3.6 delete-forw-char Ctl-D 3.6 delete-forw-char Delete 3.6 delete-forw-unit Esc D 3.6 delete-mark-to-cursor Ctl-W 3.6 delete-mark-to-cursor F8 3.6 display-ascii Esc Ctl-A 3.5 display-binary Esc Ctl-B 3.5 display-byte-shift Ctl-A 3.5 display-bytes Esc 1 3.5 display-decimal Esc Ctl-D 3.5 display-double-words Esc 4 3.5 display-ebcdic Esc Ctl-E 3.5 display-float Esc Ctl-F 3.5 display-hex Esc Backspace 3.5 display-octal Esc Ctl-O 3.5 display-swap-order Ctl-E 3.5 display-words Esc 2 3.5 BEAV User Manual 28 extended-command Esc X 3.12 file-read Ctl-X Ctl-R 3.4 file-read Sh-F2 3.4 file-save Ctl-X Ctl-S 3.4 file-save Sh-F3 3.4 file-view Ctl-X V 3.4 file-visit Ctl-X Ctl-V 3.4 file-visit Sh-F4 3.4 file-visit-split Esc U 3.4 file-write Ctl-X Ctl-W 3.4 file-write Sh-F5 3.4 help Esc ? 3.1 help F1 3.1 insert-file Ctl-F8 3.4 insert-file Ctl-X Tab 3.4 insert-file Sh-F8 3.4 insert-literally Ctl-Q 3.6 insert-literally Esc Q 3.6 insert-toggle Ctl-X Ctl-A 3.6 insert-toggle Insert 3.6 insert-unit Ctl-X I 3.6 kill-buffer Ctl-F3 3.3 kill-buffer Ctl-X K 3.3 macro-end Ctl-X ) 3.10 macro-execute Ctl-X E 3.10 macro-start Ctl-X ( 3.10 mark-set Esc . 3.2 mark-set F2 3.2 move-back-char Ctl-B 3.2 move-back-char West 3.2 move-back-line Ctl-P 3.2 move-back-line North 3.2 move-back-page Esc V 3.2 move-back-page PageDown 3.2 move-back-unit Ctl-West 3.2 move-back-unit Esc B 3.2 move-forw-char Ctl-F 3.2 move-forw-char East 3.2 move-forw-line Ctl-N 3.2 move-forw-line South 3.2 move-forw-page Ctl-V 3.2 move-forw-page PageUp 3.2 move-forw-unit Ctl-East 3.2 move-forw-unit Esc F 3.2 move-forw-unit Sh-Tab 3.2 move-to-beginning Esc < 3.2 move-to-beginning Home 3.2 move-to-buffer-split Esc G 3.2 move-to-byte Ctl-X G 3.2 move-to-byte F9 3.2 move-to-end End 3.2 move-to-end Esc > 3.2 move-window-down Ctl-X Ctl-N 3.2 move-window-down Ctl-Z 3.2 BEAV User Manual 29 move-window-up Ctl-X Ctl-P 3.2 move-window-up Esc Z 3.2 n-way-combine Esc Ctl-P 3.12 n-way-split Esc Ctl-S 3.12 print-mark-to-cursor Ctl-Print 3.9 print-mark-to-cursor Esc P 3.9 quit-no-save Ctl-C 3.8 quit-no-save Ctl-F10 3.8 quit-no-save Ctl-X Ctl-C 3.8 quit-no-save Sh-F10 3.8 quit-save-all Ctl-F9 3.8 quit-save-all Ctl-X Ctl-E 3.8 quit-save-all Sh-F9 3.8 recall-srch-string Ctl-R 3.7 refresh-screen Ctl-L 3.12 replace Esc % 3.7 replace F5 3.7 save-all-buffers Ctl-X Return 3.4 save-all-buffers Sh-F6 3.4 save-mark-to-cursor Esc O 3.3 screen-rows Esc Ctl-R 3.12 search-again Esc T 3.7 search-again F4 3.7 search-back Esc R 3.7 search-forw Esc S 3.7 search-forw F3 3.7 show-position Ctl-X = 3.2 show-save-buf Esc Ctl-W 3.3 show-version Esc Ctl-V 3.12 spawn-shell Ctl-X C 3.12 swap-cursor-and-mark Ctl-X Ctl-X 3.2 unit-twiddle Ctl-T 3.6 window-delete Ctl-X 0 3.5 window-enlarge Ctl-X Z 3.5 window-link Esc L 3.2 window-reposition Esc ! 3.5 window-shrink Ctl-X Ctl-Z 3.5 window-single Ctl-X 1 3.5 window-split Ctl-X 2 3.5 yank Ctl-Y 3.6 yank F6 3.6 yank-buffer Ctl-F6 3.3 yank-buffer Esc Y 3.3 BEAV User Manual 30 5. Alphabetical list of commands by key binding Command Key Binding Manual Section ------- ----------- -------------- delete-back-char Backspace 3.6 display-byte-shift Ctl-A 3.5 move-back-char Ctl-B 3.2 quit-no-save Ctl-C 3.8 delete-forw-char Ctl-D 3.6 display-swap-order Ctl-E 3.5 move-forw-unit Ctl-East 3.2 move-forw-char Ctl-F 3.2 buffers-display Ctl-F1 3.3 quit-no-save Ctl-F10 3.8 change-buffer Ctl-F2 3.3 kill-buffer Ctl-F3 3.3 change-to-next-buffer Ctl-F4 3.3 change-to-prev-buffer Ctl-F5 3.3 yank-buffer Ctl-F6 3.3 buffer-set-file-name Ctl-F7 3.3 insert-file Ctl-F8 3.4 quit-save-all Ctl-F9 3.8 abort-cmd Ctl-G 3.12 refresh-screen Ctl-L 3.12 move-forw-line Ctl-N 3.2 move-back-line Ctl-P 3.2 change-window-forw Ctl-PageDown 3.5 change-window-back Ctl-PageUp 3.5 print-mark-to-cursor Ctl-Print 3.9 insert-literally Ctl-Q 3.6 recall-srch-string Ctl-R 3.7 unit-twiddle Ctl-T 3.6 move-forw-page Ctl-V 3.2 delete-mark-to-cursor Ctl-W 3.6 move-back-unit Ctl-West 3.2 macro-start Ctl-X ( 3.10 macro-end Ctl-X ) 3.10 window-delete Ctl-X 0 3.5 window-single Ctl-X 1 3.5 window-split Ctl-X 2 3.5 show-position Ctl-X = 3.2 binding-for-key Ctl-X ? 3.11 change-buffer Ctl-X B 3.3 spawn-shell Ctl-X C 3.12 insert-toggle Ctl-X Ctl-A 3.6 buffers-display Ctl-X Ctl-B 3.3 quit-no-save Ctl-X Ctl-C 3.8 quit-save-all Ctl-X Ctl-E 3.8 buffer-set-file-name Ctl-X Ctl-F 3.3 abort-cmd Ctl-X Ctl-G 3.12 buffer-size-lock Ctl-X Ctl-L 3.3 move-window-down Ctl-X Ctl-N 3.2 move-window-up Ctl-X Ctl-P 3.2 file-read Ctl-X Ctl-R 3.4 BEAV User Manual 31 file-save Ctl-X Ctl-S 3.4 file-visit Ctl-X Ctl-V 3.4 file-write Ctl-X Ctl-W 3.4 swap-cursor-and-mark Ctl-X Ctl_X 3.2 window-shrink Ctl-X Ctl-Z 3.5 macro-execute Ctl-X E 3.10 move-to-byte Ctl-X G 3.2 insert-unit Ctl-X I 3.6 kill-buffer Ctl-X K 3.3 bindings-load Ctl-X L 3.11 change-window-forw Ctl-X N 3.5 change-window-back Ctl-X P 3.5 save-all-buffers Ctl-X Return 3.4 insert-file Ctl-X Tab 3.4 file-view Ctl-X V 3.4 window-enlarge Ctl-X Z 3.5 yank Ctl-Y 3.6 move-window-down Ctl-Z 3.2 delete-forw-char Delete 3.6 move-forw-char East 3.2 move-to-end End 3.2 window-reposition Esc ! 3.5 replace Esc % 3.7 change-to-next-buffer Esc + 3.3 change-to-prev-buffer Esc - 3.3 mark-set Esc . 3.2 display-bytes Esc 1 3.5 display-words Esc 2 3.5 display-double-words Esc 4 3.5 move-to-beginning Esc < 3.2 move-to-end Esc > 3.2 help Esc ? 3.1 auto-save Esc A 3.12 move-back-unit Esc B 3.2 display-hex Esc Backspace 3.5 Compare Esc C 3.12 display-ascii Esc Ctl-A 3.5 display-binary Esc Ctl-B 3.5 display-decimal Esc Ctl-D 3.5 display-ebcdic Esc Ctl-E 3.5 display-float Esc Ctl-F 3.5 abort-cmd Esc Ctl-G 3.12 delete-back-unit Esc Ctl-K 3.6 buffer-set-name Esc Ctl-N 3.3 display-octal Esc Ctl-O 3.5 n-way-combine Esc Ctl-P 3.12 screen-rows Esc Ctl-R 3.12 n-way-split Esc Ctl-S 3.12 show-version Esc Ctl-V 3.12 show-save-buf Esc Ctl-W 3.3 delete-forw-unit Esc D 3.6 move-forw-unit Esc F 3.2 move-to-buffer-split Esc G 3.2 bind-to-key Esc K 3.11 BEAV User Manual 32 window-link Esc L 3.2 save-mark-to-cursor Esc O 3.3 print-mark-to-cursor Esc P 3.9 insert-literally Esc Q 3.6 search-back Esc R 3.7 delete-back-unit Esc Rubout 3.6 search-forw Esc S 3.7 search-again Esc T 3.7 file-visit-split Esc U 3.4 move-back-page Esc V 3.2 copy-mark-to-cursor Esc W 3.6 extended-command Esc X 3.12 yank-buffer Esc Y 3.3 move-window-up Esc Z 3.2 help F1 3.1 abort-cmd F10 3.12 mark-set F2 3.2 search-forw F3 3.7 search-again F4 3.7 replace F5 3.7 yank F6 3.6 copy-mark-to-cursor F7 3.6 delete-mark-to-cursor F8 3.6 move-to-byte F9 3.2 move-to-beginning Home 3.2 insert-toggle Insert 3.6 move-back-line North 3.2 move-back-page PageDown 3.2 move-forw-page PageUp 3.2 delete-back-char Rubout 3.6 binding-for-key Sh-F1 3.11 quit-no-save Sh-F10 3.8 file-read Sh-F2 3.4 file-save Sh-F3 3.4 file-visit Sh-F4 3.4 file-write Sh-F5 3.4 save-all-buffers Sh-F6 3.4 buffer-set-file-name Sh-F7 3.3 insert-file Sh-F8 3.4 quit-save-all Sh-F9 3.8 move-forw-unit Sh-Tab 3.2 move-forw-line South 3.2 move-back-char West 3.2 BEAV User Manual 33 6. Release notes 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. Version 1.30 (7/1/91) of BEAV contains the following fixes and enhancements; * Under MSDOS and 16 bit UNIX systems the kill or copy region could not be over 64K bytes. This limit has been eliminated. * The save buffer can be made visible with the Esc Ctl- W command. The save buffer is not editable. * All memory allocation errors now pause and ask for conformation before continuing. In previous releases only an error message was printed. Since an allocation error generally means data loss, I have forced the user to respond. Memory allocation errors are not otherwise fatal to BEAV, they are probably fatal to the user's data. The decision is left to the user with the appropriate warning. * Two commands have been added to aid in working with PROM files; n-way-split (Esc Ctl-S) and n-way-combine (Esc Ctl-P). * BEAV User Manual 34 The speed of the delete-mark-to-cursor (Ctl-W) command has been greatly improved. * All commands that can potentially take a lot of time can be stopped by pressing Ctl-G. Version 1.31 (11/2/91) of BEAV contains the following fixes; * A serious bug that causes a crash on systems that trapped the use of dereferenced pointers has been fixed. * BEAV now names the backup file properly under unix. Previously; if a dot file (.) was edited, the backup file was given a garbage name. Now, a backup file simply has ".bak" appended to the file name. * You can use the buffers-display (Ctl-X, Ctl-B) command to; go to, kill, or save a buffer. * A compile flag for DEC ULTRA was created and a makeable is included in this release (makefile.utx). * When a large region was deleted the offset value was displayed wrong, this is now fixed. * A bug in the parse_f_name that trashed a variable is now fixed. * Regions of never used code have been deleted. * Under UNIX the file permissions are maintained correctly when the file is saved. * A number of un-niceties that lint reported have been fixed. Version 1.32 (11/8/91) of BEAV contains the following enhancements; * BEAV will now compile and run on the Amiga computer. Version 1.33 (8/9/92) of BEAV contains the following enhancements; * A new command, "screen-rows", allows you to change the number of rows that BEAV will use on the CRT. The command can be issued anytime, the windows will be adjusted or killed as necessary. BEAV User Manual 35 * Floating point numbers can be displayed using the "display-float" command. This will set the current window to floating point display, but the window cannot be edited. * The "beavrc" file processing has been enhanced to allow most commands to be executed from the rc file when BEAV loads. * The default key binding for the "n-way-combine" has been changed to Esc Ctl P. This frees up the old binding Esc Ctl F to be used for the "display-float" command which is more in line with the other display mode commands. * The replace command would fail to find all occurrences of a search pattern if the pattern fell on the boundary of certain internal data structures. This is fixed. * The memory used to handle screen images is now allocated at load time rather than statically allocated. This will allow systems with any screen size to be fully used. This depends on the variable "nrow" being properly set by whatever termcap description you have configured. The default for "nrow" is the #define "NROW" as set in the def.h file, generally 24. The columns remain fixed at 80. * Under Unix, BEAV will use the full screen rows as reported by the ioctl inquiry of the tty device. Previously, the bottom line was not used. * Under MSDOS, BEAV will use the full screen rows as reported by the int 10 function 1b call. * Not new to this release, but important for foreign language users. All English text in BEAV is contained in the file "text.c". It should be relatively easy to translate and recompile. If someone wants to send me a translated version of "text.c", I will include it in my next release. * The prompt line is now erased properly. Version 1.40 (2/20/93) of BEAV contains the following enhancements; * Support for different languages. All English text strings are contained in a separate file. I would like to get translations to other languages. I will then include them in future releases. * A bug has been fixed in the search command. If the backspace key was hit while entering the search string, some error messages were displayed. BEAV User Manual 36 * A bug has been fixed in the search command. If the backspace key was hit while entering the search string, someerror messages were displayed. * Another bug has been fixed in the search command. While entering a search pattern if you went back and inserted characters in the search pattern the cursor would advance one position too far. * BEAV will compile under OS/2. There is a makefile called makefile.os2. The OS/2 support is thanks to Kai Uwe Rommel (rommel@jonas.gold.sub.org) 7. Source Availability BEAV source and executable is maintained at WSMR- SIMTEL20.ARMY.MIL in PD1:BEAV140.ZIP. The source and manual is available in PD1:BEAV140S.ZIP. If anyone does not have access to usenet, I will mail a copy of the source on floppy for $20.00 copying charge. The floppies can be in MSDOS file format or UNIX tar format. I can also supply either QIC-24, QIC-120, QIC-150, or 9 track reel to reel tape. The price for the tape will include the cost of the media. beav-140/beav32.def0000644000175000001440000000014505667134707014015 0ustar samusers00000000000000NAME BEAV WINDOWCOMPAT NEWFILES DESCRIPTION 'Binary (file) editor and viewer' STACKSIZE 0x10000 beav-140/buffer.c0000644000175000001440000005044205667134707013675 0ustar samusers00000000000000/* * Buffer handling. */ #include "def.h" bool onebuf (); bool killablebufs (); bool _yankbuffer (); char next_buf (); bool bclear (); bool addline (); char makelist (); bool popblist (); char listbuffers (); char _killbuffer (); bool _usebuffer (); extern ROW_FMT text_fmt; extern char MSG_use_b[]; extern char MSG_kill_b[]; extern char MSG_not_fnd[]; extern char MSG_no_del_m[]; extern char MSG_buf_disp[]; extern char MSG_main[]; extern char MSG_l_buf_h[]; extern char MSG_l_buf_h1[]; extern char MSG_no_chg[]; extern char MSG_yank_b[]; extern char MSG_no_buf[]; extern char MSG_no_s_yank[]; extern char MSG_buf_nam[]; extern char MSG_bad_l[]; extern char MSG_pick[]; extern char MSG_siz_chg[]; extern char MSG_no_siz_chg[]; extern char MSG_up_arrow[]; extern char MSG_null[]; extern char MSG_save_buf[]; extern char MSG_cnt_al_b[]; extern char MSG_ins_cnt[]; BUFFER sav_buf; LINE sav_line_h; /* * Attach a buffer to a window. The * values of dot and mark come from the buffer * if the use count is 0. Otherwise, they come * from some other window. * * plus hacks for prev/next buffer and use-buffer-split (jam) * functions (like in file.c) */ char usebuffer () { char bufn[NBUFN]; register char s; if ((s = ereply (MSG_use_b, bufn, NBUFN, 0)) != TRUE) return (s); return (_usebuffer (bufn)); } /* use buffer, split window first */ char use_buffer () { char bufn[NBUFN]; register char s; if ((s = ereply (MSG_use_b, bufn, NBUFN, 0)) != TRUE) return (s); splitwind (); return (_usebuffer (bufn)); } /* does all the work for changing to a new buffer for use-buffer, * use-buffer-split and prev-buff & next-buff */ bool _usebuffer (bufn) char *bufn; { register BUFFER *bp; register WINDOW *wp; if (strcmp (MSG_kill_b, bufn) == 0) /* hack! */ bp = blistp; else if ((bp = bfind (bufn, TRUE)) == NULL) return (FALSE); /* if current buffer is special and new buffer is normal */ /* set to hex byte mode */ if ((curbp == blistp) && (R_TYPE (curwp) == TEXT)) { dispsize1 (); hexmode (); } if (--curbp->b_nwnd == 0) { /* Last use. */ curbp->b_dotp = curwp->w_dotp; curbp->b_doto = curwp->w_doto; curbp->b_unit_offset = curwp->w_unit_offset; /* pvr */ curbp->b_markp = curwp->w_markp; curbp->b_marko = curwp->w_marko; } curbp = bp; /* Switch. */ curwp->w_bufp = bp; curwp->w_linep = bp->b_linep; /* For macros, ignored. */ curwp->w_loff = 0; /* pvr */ curwp->w_flag |= WFMODE | WFFORCE | WFHARD; /* Quite nasty. */ if (bp->b_nwnd++ == 0) { /* First use. */ curwp->w_dotp = bp->b_dotp; curwp->w_doto = bp->b_doto; curwp->w_unit_offset = 0; /* pvr */ curwp->w_markp = bp->b_markp; curwp->w_marko = bp->b_marko; wind_on_dot (curwp); /* if we are in the funny TEXT mode then goto standard HEX mode */ if (R_TYPE (curwp) == TEXT) hexmode (); return (TRUE); } wp = wheadp; /* Look for old. */ while (wp != NULL) { if (wp != curwp && wp->w_bufp == bp) { curwp->w_dotp = wp->w_dotp; curwp->w_doto = wp->w_doto; curwp->w_unit_offset = wp->w_unit_offset; /* pvr */ curwp->w_markp = wp->w_markp; curwp->w_marko = wp->w_marko; break; } wp = wp->w_wndp; } wind_on_dot (curwp); /* if we are in the funny TEXT mode then goto standard HEX mode */ if (R_TYPE (curwp) == TEXT) hexmode (); return (TRUE); } /* * Dispose of a buffer, by name. * Ask for the name. Look it up (don't get too * upset if it isn't there at all!). Get quite upset * if the buffer is being displayed. Clear the buffer (ask * if the buffer has been changed). Then free the header * line and the buffer header. Bound to "C-X K". */ char killbuffer () { register char s; char bufn[NBUFN]; if ((s = ereply (MSG_kill_b, bufn, NBUFN, 0)) != TRUE) return (s); if (s = _killbuffer (bufn)) writ_echo (okmsg); /* verbose-ness (jam) */ return (s); } char _killbuffer (bufn) char *bufn; { register BUFFER *bp, *bp1, *bp2; register char s, x = 0; if (((bp = bfind (bufn, FALSE)) == NULL) || !strcmp (bufn, MSG_save_buf)) { writ_echo (MSG_not_fnd); return (FALSE); } if (killablebufs (bp)) /* can't kill '?' if no other buffers */ { writ_echo (MSG_no_del_m); return (FALSE); } /* see if the buffer to be killed is in a window */ bp1 = bp; if (curbp == blistp && onebuf (bp)) /* Hack ! */ { next_buf (); onlywind (); update (); } if (bp->b_nwnd > 0) { if ((s = eyesno (MSG_buf_disp)) != TRUE) return (s); /* make the current window the only window if it is to die */ onlywind (); if (curbp == bp) { next_buf (); if (curbp == bp) x++; } } if ((s = bclear (bp)) != TRUE) /* Blow text away. */ { if (bp1 == blistp) /* special buffer */ curbp = bp1; else if (!x) _usebuffer (bp1->b_bname); /* back to original buffer (jam) */ return (s); } if (x) { _usebuffer (MSG_main); x++; } free ((char *) bp->b_linep);/* Release header line. */ bp1 = NULL; /* Find the header. */ bp2 = bheadp; while (bp2 != bp) { bp1 = bp2; bp2 = bp2->b_bufp; } bp2 = bp2->b_bufp; /* Next one in chain. */ if (bp1 == NULL) /* Unlink it. */ bheadp = bp2; else bp1->b_bufp = bp2; free ((char *) bp); /* Release buffer block */ if (x) update (); /* update buffer display */ if ((blistp->b_nwnd != 0) && (blistp->b_type == BTLIST)) listbuffers (); return (TRUE); } /* * Display the buffer list. This is done * in two parts. The "makelist" routine figures out * the text, and puts it in the buffer whoses header is * pointed to by the external "blistp". The "popblist" * then pops the data onto the screen. Bound to * "C-X C-B". */ char listbuffers () { register char s; if ((s = makelist ()) != TRUE) return (s); return (popblist ()); } /* * Display the save buffer contents. * Bound to "Meta C-W". */ char showsavebuf () { WINDOW *wp; if (sav_buf.b_nwnd == 0) { splitwind (); _usebuffer (MSG_save_buf); } else { wp = wheadp; /* Look for old. */ while (wp != NULL) { if (wp->w_bufp == &sav_buf) { wp->w_flag |= WFMODE | WFFORCE | WFHARD; break; } wp = wp->w_wndp; } } return (TRUE); } /* * Pop the special buffer whose * buffer header is pointed to by the external * variable "blistp" onto the screen. This is used * by the "listbuffers" routine (above) and by * some other packages. Returns a status. */ bool popblist () { register WINDOW *wp; register BUFFER *bp; if (blistp->b_nwnd == 0) /* Not on screen yet. */ { if ((wp = wpopup ()) == NULL) return (FALSE); bp = wp->w_bufp; if (--bp->b_nwnd == 0) { bp->b_dotp = wp->w_dotp; bp->b_doto = wp->w_doto; bp->b_unit_offset = wp->w_unit_offset; /* pvr */ bp->b_markp = wp->w_markp; bp->b_marko = wp->w_marko; } curwp = wp; curbp = blistp; wp->w_bufp = blistp; ++blistp->b_nwnd; } wp = wheadp; while (wp != NULL) { if (wp->w_bufp == blistp) { wp->w_linep = lforw (blistp->b_linep); wp->w_loff = 0; wp->w_dotp = lforw (blistp->b_linep); wp->w_doto = 0; wp->w_unit_offset = 0; wp->w_markp = NULL; wp->w_marko = 0; wp->w_disp_shift = 0; wp->w_intel_mode = FALSE; wp->w_fmt_ptr = &text_fmt; wp->w_flag |= WFMODE | WFHARD; } wp = wp->w_wndp; } return (TRUE); } /* * This routine rebuilds the * text in the special secret buffer * that holds the buffer list. It is called * by the list buffers command. Return TRUE * if everything works. Return FALSE if there * is an error (if there is no memory). */ char makelist () { register char *cp1; register char *cp2; register int c; register BUFFER *bp; register A32 nbytes; register char s; char b[8 + 1]; char line[128]; blistp->b_flag &= ~BFCHG; /* Blow away old. */ if ((s = bclear (blistp)) != TRUE) return (s); blistp->b_flag |= BFVIEW; blistp->b_type = BTLIST; strcpy (blistp->b_fname, MSG_up_arrow); if (addline (MSG_l_buf_h) == FALSE || addline (MSG_l_buf_h1) == FALSE) return (FALSE); bp = bheadp; /* For all buffers */ while (bp != NULL) { cp1 = &line[0]; /* Start at left edge */ if ((bp->b_flag & BFCHG) != 0) /* "*" if changed */ *cp1++ = '*'; else if (bp->b_flag & BFVIEW) /* jam */ *cp1++ = 'R'; /* readonly */ else *cp1++ = ' '; *cp1++ = ' '; /* Gap. */ if ((bp->b_flag & BFBAD) != 0) /* "?" if maybe trashed */ *cp1++ = '?'; else *cp1++ = ' '; *cp1++ = ' '; /* Gap. */ nbytes = bp->b_linep->l_bp->l_file_offset + bp->b_linep->l_bp->l_used; sprintf (b, "%8lx", nbytes); /* 8 digit buffer size. */ cp2 = &b[0]; while ((c = *cp2++) != 0) *cp1++ = c; *cp1++ = ' '; /* Gap. */ cp2 = &bp->b_bname[0]; /* Buffer name */ while ((c = *cp2++) != 0) *cp1++ = c; *cp1++ = ' '; /* Gap. */ *cp1++ = ' '; /* Gap. */ cp2 = &bp->b_fname[0]; /* File name */ if (*cp2 != 0) { while (cp1 < &line[1 + 1 + 1 + 1 + 6 + 1 + NBUFN + 1]) *cp1++ = ' '; while ((c = *cp2++) != 0) { if (cp1 < &line[128 - 1]) *cp1++ = c; } } while (cp1 < &line[80]) /* Fill out line to col 80 */ *cp1++ = ' '; *cp1 = 0; /* Add to the buffer. */ if (addline (line) == FALSE) return (FALSE); bp = bp->b_bufp; } return (TRUE); /* All done */ } /* * The argument "text" points to * a string. Append this line to the * buffer list buffer. * Return TRUE if it worked and * FALSE if you ran out of room. */ bool addline (text) char *text; { register LINE *lp; register int i, allocsize; register int ntext; ntext = strlen (text); allocsize = 128; if ((lp = lalloc (allocsize)) == NULL) return (FALSE); for (i = 0; i < ntext; ++i) lputc (lp, i, text[i]); for (; i < allocsize; ++i) /* fill out line with spaces */ lputc (lp, i, ' '); blistp->b_linep->l_bp->l_fp = lp; /* Hook onto the end */ lp->l_bp = blistp->b_linep->l_bp; blistp->b_linep->l_bp = lp; lp->l_fp = blistp->b_linep; lp->l_size = allocsize; /* line size is limited to 80 chars */ lp->l_used = allocsize; lp->l_file_offset = lp->l_bp->l_file_offset + lp->l_bp->l_used; if (blistp->b_dotp == blistp->b_linep) /* If "." is at the end */ blistp->b_dotp = lp; /* move it to new line */ return (TRUE); } /* * Look through the list of * buffers. Return TRUE if there * are any changed buffers. Special buffers * like the buffer list buffer don't count, as * they are not in the list. Return FALSE if * there are no changed buffers. */ bool anycb () { register BUFFER *bp; bp = bheadp; while (bp != NULL) { if ((bp->b_flag & BFCHG) != 0) return (TRUE); bp = bp->b_bufp; } return (FALSE); } /* * Search for a buffer, by name. * If not found, and the "cflag" is TRUE, * create a buffer and put it in the list of * all buffers. Return pointer to the BUFFER * block for the buffer. */ BUFFER * bfind (bname, cflag) register char *bname; int cflag; { register BUFFER *bp; bp = bheadp; while (bp != NULL) { if (strcmp (bname, bp->b_bname) == 0) return (bp); bp = bp->b_bufp; } if (cflag != FALSE && (bp = bcreate (bname)) != NULL) { bp->b_bufp = bheadp; bheadp = bp; } return (bp); } /* * Create a buffer, by name. * Return a pointer to the BUFFER header * block, or NULL if the buffer cannot * be created. The BUFFER is not put in the * list of all buffers; this is called by * "edinit" to create the buffer list * buffer. */ BUFFER * bcreate (bname) register char *bname; { register BUFFER *bp; register LINE *lp; if ((bp = (BUFFER *) malloc (sizeof (BUFFER))) == NULL) { err_echo (MSG_cnt_al_b); return (NULL); } if ((lp = lalloc (0)) == NULL) { free ((char *) bp); return (NULL); } bp->b_bufp = NULL; bp->b_dotp = lp; bp->b_doto = 0; bp->b_unit_offset = 0; /* unit offset pvr */ bp->b_markp = NULL; bp->b_marko = 0; bp->b_flag = 0; bp->b_nwnd = 0; bp->b_linep = lp; strcpy (bp->b_fname, MSG_null); strcpy (bp->b_bname, bname); lp->l_fp = lp; lp->l_bp = lp; lp->l_file_offset = 0; /* pvr */ lp->l_used = 0; /* pvr */ lp->l_size = 0; /* size of zero indicates the header line pvr */ return (bp); } /* * This routine blows away all of the text * in a buffer. If the buffer is marked as changed * then we ask if it is ok to blow it away; this is * to save the user the grief of losing text. The * window chain is nearly always wrong if this gets * called; the caller must arrange for the updates * that are required. Return TRUE if everything * looks good. */ bool bclear (bp) register BUFFER *bp; { register LINE *lp; register char s; if ((bp->b_flag & BFCHG) != 0 /* Changed. */ && (s = eyesno (MSG_no_chg)) != TRUE) return (s); bp->b_flag &= ~BFCHG; /* Not changed */ while ((lp = lforw (bp->b_linep)) != bp->b_linep) lfree (lp); bp->b_dotp = bp->b_linep; /* Fix "." */ bp->b_doto = 0; bp->b_unit_offset = 0; /* pvr */ bp->b_markp = NULL; /* Invalidate mark */ bp->b_marko = 0; return (TRUE); } /* flip to next buffer in the list, wrap * to beginning if required (wrap around) * (skips buffers saved by save-region) */ char next_buf () { register BUFFER *bp; bp = curbp; while (TRUE) { if (!(bp = bp->b_bufp)) bp = bheadp; if ((bp->b_type == BTSAVE) || (bp->b_type == BTLIST) || (bp->b_type == BTHELP)) continue; break; } _usebuffer (bp->b_bname); return (TRUE); } /* flip to prev buffer in the list, wrap * to end if required (wrap around) * (does NOT skip buffers saved by save-region) */ char prev_buf () { register BUFFER *sp; if ((sp = curbp) == bheadp) /* front of list */ { for (; sp->b_bufp; sp = sp->b_bufp) ; } else /* cycle around */ { for (sp = bheadp; sp->b_bufp; sp = sp->b_bufp) { if (sp->b_bufp == curbp) break; } } return (_usebuffer (sp->b_bname)); } /* yank a buffer into current buffer */ char yank_buffer () { char bufn[NBUFN]; if (ereply (MSG_yank_b, bufn, NBUFN, 0) != TRUE) return (FALSE); return (_yankbuffer (bufn)); } bool _yankbuffer (bufn) char *bufn; { register LINE *lp; register BUFFER *bp = curbp; register int s; A32 cnt; char buf[NFILEN], buf1[NFILEN]; if ((bp = bfind (bufn, FALSE)) == NULL) { writ_echo (MSG_no_buf); return (FALSE); } if (strcmp (bp->b_bname, curbp->b_bname) == 0) { writ_echo (MSG_no_s_yank); return (FALSE); } cnt = 0; lp = lforw (bp->b_linep); while (TRUE) { cnt += lp->l_used; for (s = 0; s < lp->l_used; s++) if (linsert (1, lp->l_text[s]) == FALSE) return (FALSE); if ((lp = lforw (lp)) == bp->b_linep) { break; } if ((cnt & 0x7ff) == 0) { sprintf (buf1, MSG_ins_cnt, R_POS_FMT (curwp)); sprintf (buf, buf1, cnt); writ_echo (buf); /* check if we should quit */ if (ttkeyready ()) { l_fix_up (lp->l_bp); wind_on_dot_all (); if (ttgetc () == CTL_G) /* was it an abort key? */ return (FALSE); } } } writ_echo (okmsg); return (TRUE); } bool buffername () { register WINDOW *wp; register char *p; register char s; char bname[NBUFN + 1]; if ((s = ereply (MSG_buf_nam, bname, NBUFN, 0)) == ABORT) return (s); for (p = bname; *p && *p != ' '; p++) ; *p = 0; /* no blanks */ strcpy (curbp->b_bname, bname); wp = wheadp; /* Update mode lines. */ while (wp != NULL) { if (wp->w_bufp == curbp) wp->w_flag |= WFMODE; wp = wp->w_wndp; } if ((blistp->b_nwnd != 0) &&/* update buffer display */ (blistp->b_type == BTLIST)) listbuffers (); return (TRUE); } /* any killable buffers around ? (jam) */ bool killablebufs (bp) register BUFFER *bp; { if (strcmp (bp->b_bname, MSG_main) == 0) /* doomed buffer is 'empty' */ if (bheadp == bp) /* and is only buffer in list */ if (bheadp->b_bufp == 0) /* then there are no killable buffers */ return (TRUE); return (FALSE); } /* only 1 buffer around ? */ bool onebuf (bp) register BUFFER *bp; { if (strcmp (bp->b_bname, bheadp->b_bname) == 0) if (bheadp->b_bufp == 0) return (TRUE); return (FALSE); } /* funky new name; real yukky!!!! (jam) */ void funky_name (bname, n) register char *bname; int n; { char num[10]; register int i; register char *p; for (i = 0; i < 10; i++) num[i] = ' '; for (p = bname; *p; p++) *p = 0; *bname++ = '#'; sprintf (num, "%lx", (long) n + 1); for (p = num; *p; p++) if (*p != ' ') *bname++ = *p; *bname = 0; } /* pick a buffer to goto/kill */ #define BUFFEROFFSET (13) /* depends on makelist !! */ bool pickone () { register int s, i, c; register LINE *lp; char name[NBUFN + 1]; char buf[3]; WINDOW *wp; lp = curwp->w_dotp; /* get the buffer name from the line */ i = 0; if (!llength (lp)) { writ_echo (MSG_bad_l); return (FALSE); } for (s = BUFFEROFFSET; (c = lgetc (lp, s)) != ' '; s++) { name[i++] = c; if (s >= llength (lp)) break; } name[i] = 0; if (!bfind (name, FALSE)) { writ_echo (MSG_bad_l); return (FALSE); } loop: if ((s = ereply (MSG_pick, buf, 2, name)) != TRUE) return (FALSE); if (ISLOWER (buf[0]) != FALSE) buf[0] = TOUPPER (buf[0]); if (buf[0] == 'K') _killbuffer (name); else if (buf[0] == 'G') _usebuffer (name); else if (buf[0] == 'S') { _usebuffer (name); /* goto this buffer, but don't show the user */ filesave (); _usebuffer (MSG_kill_b); /* jump back to this window - HACK ! */ listbuffers (); /* update the list */ } else goto loop; writ_echo (MSG_null); return (TRUE); } /* * Toggle the buffer size lock bit. */ char bufsizlock () { if (curbp->b_flag & BFSLOCK) { curbp->b_flag &= ~BFSLOCK; writ_echo (MSG_siz_chg); } else { if (insert_mode) insert_toggle (); curbp->b_flag |= BFSLOCK; writ_echo (MSG_no_siz_chg); } return (TRUE); } /* * Append the given line to the end of the given buffer. */ void b_append_l (buf_p, lp) BUFFER *buf_p; LINE *lp; { LINE *h_lp; h_lp = buf_p->b_linep; lp->l_fp = h_lp; lp->l_bp = h_lp->l_bp; lp->l_bp->l_fp = lp; h_lp->l_bp = lp; lp->l_file_offset = lp->l_bp->l_file_offset + lp->l_bp->l_used; } /* * Append the given line to the end of the given buffer. */ bool b_append_c (buf_p, ch) BUFFER *buf_p; D8 ch; { LINE *lp; lp = buf_p->b_linep->l_bp; /* get last line */ /* do I need to get a new line? */ if (lp->l_size <= lp->l_used) { if ((lp = lalloc (KBLOCK)) == NULL) return (FALSE); lp->l_fp = buf_p->b_linep; lp->l_bp = buf_p->b_linep->l_bp; lp->l_bp->l_fp = lp; buf_p->b_linep->l_bp = lp; lp->l_file_offset = lp->l_bp->l_file_offset + lp->l_bp->l_used; } lp->l_text[lp->l_used++] = ch; return (TRUE); } /* * Initialize the save buffer. */ void save_buf_init () { register BUFFER *bp; sav_line_h.l_fp = &sav_line_h; sav_line_h.l_bp = &sav_line_h; sav_line_h.l_file_offset = 0; sav_line_h.l_used = 0; sav_line_h.l_size = 0; sav_buf.b_type = BTSAVE; sav_buf.b_bufp = NULL; sav_buf.b_dotp = &sav_line_h; sav_buf.b_doto = 0; sav_buf.b_unit_offset = 0; sav_buf.b_markp = NULL; sav_buf.b_marko = 0; sav_buf.b_linep = &sav_line_h; sav_buf.b_nwnd = 0; sav_buf.b_flag = BFVIEW; sav_buf.b_begin_addr = 0; sav_buf.b_file_size = 0; sav_buf.b_fname[0] = 0; strcpy (sav_buf.b_bname, MSG_save_buf); /* put on end of chain */ bp = bheadp; while ((bp->b_bufp) != NULL) bp = bp->b_bufp; bp->b_bufp = &sav_buf; } /* * Set the save buffer dot pointer to the begining. */ void save_buf_home () { sav_buf.b_dotp = sav_buf.b_linep->l_fp; sav_buf.b_doto = 0; sav_buf.b_flag = BFVIEW; } D16 get_save_char () { D8 ch; /* are we past the end of the buffer */ if (sav_buf.b_dotp == sav_buf.b_linep) return (-1); ch = sav_buf.b_dotp->l_text[sav_buf.b_doto++]; if (sav_buf.b_doto >= sav_buf.b_dotp->l_used) { sav_buf.b_doto = 0; sav_buf.b_dotp = sav_buf.b_dotp->l_fp; } return ((D16) ch); } beav-140/cinfo.c0000644000175000001440000000471305667134707013522 0ustar samusers00000000000000/* * Character class tables. * Do it yourself character classification * macros, that understand the multinational character set, * and let me ask some questions the standard macros (in * ctype.h) don't let you ask. */ #include "def.h" /* * This table, indexed by a character drawn * from the 256 member character set, is used by my * own character type macros to answer questions about the * type of a character. It handles the full multinational * character set, and lets me ask some questions that the * standard "ctype" macros cannot ask. */ char cinfo[256] = { _C, _C, _C, _C, /* 0x0X */ _C, _C, _C, _C, _C, _C, _C, _C, _C, _C, _C, _C, _C, _C, _C, _C, /* 0x1X */ _C, _C, _C, _C, _C, _C, _C, _C, _C, _C, _C, _C, 0, 0, 0, 0, /* 0x2X */ _W, 0, 0, _W, 0, 0, 0, 0, 0, 0, 0, 0, _W, _W, _W, _W, /* 0x3X */ _W, _W, _W, _W, _W, _W, 0, 0, 0, 0, 0, 0, 0, _U | _W, _U | _W, _U | _W, /* 0x4X */ _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, /* 0x5X */ _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, 0, 0, 0, 0, _W, 0, _L | _W, _L | _W, _L | _W, /* 0x6X */ _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, /* 0x7X */ _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, 0, 0, 0, 0, _C, 0, 0, 0, 0, /* 0x8X */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9X */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xAX */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xBX */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _U | _W, _U | _W, _U | _W, _U | _W, /* 0xCX */ _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, 0, _U | _W, _U | _W, _U | _W, /* 0xDX */ _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, _U | _W, 0, _W, _L | _W, _L | _W, _L | _W, _L | _W, /* 0xEX */ _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, 0, _L | _W, _L | _W, _L | _W, /* 0xFX */ _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, _L | _W, 0, 0 }; beav-140/def.h0000644000175000001440000005050305667134707013165 0ustar samusers00000000000000/* * Common header file. * * This file is the general header file for all parts * of the display editor. It contains all of the * general definitions and macros. It also contains some * conditional compilation flags. All of the per-system and * per-terminal definitions are in special header files. * The most common reason to edit this file would be to zap * the definition of CVMVAS or BACKUP. */ #define LINT_ARGS 1 /* enable lint type checking */ #include "stdio.h" #ifdef UNIX #include "sys/types.h" #endif /* UNIX */ #define BACKUP 1 /* Make backup file. */ #define RUNCHK 1 /* Do additional checking at run time */ #ifndef uchar #define uchar unsigned char #endif #ifndef uint #define uint unsigned int #endif #ifndef ushort #define ushort unsigned short #endif #ifndef ulong #define ulong unsigned long #endif /* these defines are reserved for handling data values from the buffer */ #define D8 uchar /* this had better be a 8 bit quantity */ #define D16 ushort /* this had better be a 16 bit quantity */ #define D32 ulong /* this had better be a 32 bit quantity */ #define D64 double /* this had better be a 64 bit quantity */ /* this define is reserved for the address of a location in the buffer */ #define A32 ulong /* this is a 32 bit address into the buffer */ #define bool char /* used for boolean values */ #define bits char /* used for boolean bit flags */ /* this define is reserved for the byte location in the a LINE structure */ #define LPOS uint /* this is a 32 bit address into the buffer */ /* * MS-DOS system header file. */ #if MSDOS #define LARGE 1 /* Large model. */ #endif #define PCC 1 /* "[]" won't work. */ #define GOOD 0 /* Indicate hunkydoryhood */ /* * Macros used by the buffer name making code. * Start at the end of the file name, scan to the left * until BDC1 (or BDC2, if defined) is reached. The buffer * name starts just to the right of that location, and * stops at end of string (or at the next BDC3 character, * if defined). BDC2 and BDC3 are mainly for VMS. */ #define BDC1 ':' /* Buffer names. */ #define BDC2 '/' /* Buffer names. jam */ #ifdef UNIX #define PATHCHR ':' #define SEPCHAR '/' #else #define PATHCHR ';' #define SEPCHAR 0x5c /* this is a \ char */ #endif /* * This enables the float mode of BEAV. Some systems may handle * floats in a way that is not compatible with BEAV. BEAV was * written on Intel machines. * * The Intel floating point representation is; * bit 0 - 52 significand (53 bits) * bit 53 - 62 biased exponent (11 bits) * bit 63 sign * maximum range; 10^-308 <= X <= 10^+308 * obviously, not all patterns are legal floating point numbers. * There can be up to 16 decimal digits of significand. * There are only 3 decimal digits of exponent (308 max). * * BEAV uses printf to display floating point numbers so it should * transport with minimal work. The printf format string is * called "MSG_116e" and is defined in text.c. I have specified * 16 digits of precision and scientific notation. If you need * too many more digits of precision the displayed columns may * overwrite each other. This can be fixed by editing the * format.c file. The display format can be altered by changing * the "float_64_fmt" data. This is more complicated, however. * * If it cannot be made to work, turn this off. */ #define FLOAT_DISP 1 /* * Digital ANSI terminal header file */ #ifdef MSDOS #define ANSI 1 /* send ANSI escape codes */ #endif #ifdef OS2 #define NCOL 132 /* Columns. */ #else #define NCOL 80 /* Columns. */ #endif #define NROW 24 /* default rows */ #define CUSTOMIZE /* compile switch for extended key binding in extend.c */ #define COSMETIC /* cosmetic screen stuff on insert off screen */ #ifdef MSDOS #define WANG_CHARACTER_SCREEN 0xf0000000L #endif /* * Table sizes, etc. */ #define NSHASH 31 /* Symbol table hash size. */ #define NFILEN 256 /* Length, file name. */ #define NBUFN 13 /* Length, buffer name. */ #define NFILE 12 /* Length, file name. */ /* krw */ #define NKBDM 256 /* Length, keyboard macro. */ #define NMSG 512 /* Length, message buffer. */ #define NPAT 80 /* Length, pattern. */ #define HUGE 1000 /* A rather large number. */ #define NSRCH 128 /* Undoable search commands. */ #define NXNAME 64 /* Length, extended command. */ #define MAXPOS 0x7FFFFFFF /* Maximum positive long value */ #define MIN_WIN_ROWS 3 /* Minimum number of rows in a window */ /* * This is the initial allocation for user data storage. * It has should be in the range of 1 to less than half the size * of an int. The define LPOS is used to index into an array of this size. * This is main tunable parameter for the speed of beav. * If it is too large inserts and deletes will be slow but * file loads will be fast and memory will be efficiently used. * If it is too small the reverse will be true. * This seems like a good number, but I have not tested it for performance. */ #define NLINE 0x1000 /* Length, line. pvr */ /* * When memory must be reallocated this is added to the allocation * request to allow for a little slop on areas that are being worked on. * This should reduce the number of allocations done. */ #define NBLOCK 0x1000 /* Line block extra size */ /* * This is the number of bytes that are allocated for the kill buffer * when data cannot be moved by changing the pointers. */ #define KBLOCK 0x1000 /* Kill buffer block size. */ /* * Universal. */ #define FALSE 0 /* False, no, bad, etc. */ #define TRUE 1 /* True, yes, good, etc. */ #define ABORT 2 /* Death, ^G, abort, etc. */ /* * These flag bits keep track of * some aspects of the last command. * The CFKILL flag controls the clearing versus appending * of data in the kill buffer. */ #define CFKILL 0x0002 /* Last command was a kill */ /* * File I/O. */ #define FIOSUC 0 /* Success. */ #define FIOFNF 1 /* File not found. */ #define FIOEOF 2 /* End of file. */ #define FIOERR 3 /* Error. */ /* * Directory I/O. */ #define DIOSUC 0 /* Success. */ #define DIOEOF 1 /* End of file. */ #define DIOERR 2 /* Error. */ /* * Display colors. */ #define CNONE 0 /* Unknown color. */ #define CTEXT 1 /* Text color. */ #define CMODE 2 /* Mode line color. */ /* * Flags for "eread". */ #define EFNEW 0x0001 /* New prompt. */ #define EFAUTO 0x0002 /* Autocompletion enabled. */ #define EFCR 0x0004 /* Echo CR at end; last read. */ /* * Keys are represented inside using an 12 bit * keyboard code. The transformation between the keys on * the keyboard and 12 bit code is done by terminal specific * code in the "kbd.c" file. The actual character is stored * in 8 bits (DEC multinationals work); there is also a control * flag KCTRL, a meta flag KMETA, and a control-X flag KCTLX. * ASCII control characters are always represented using the * KCTRL form. Although the C0 control set is free, it is * reserved for C0 controls because it makes the communication * between "getkey" and "getkbd" easier. The funny keys get * mapped into the C1 control area. */ #define NKEYS 4096 /* 12 bit code. */ #define METACH 0x1B /* M- prefix, Control-[, ESC */ #define CTMECH 0x1C /* C-M- prefix, Control-\ */ #define EXITCH 0x1D /* Exit level, Control-] */ #define CTRLCH 0x1E /* C- prefix, Control-^ */ #define HELPCH 0x1F /* Help key, Control-_ */ #define CTL_G 0x07 /* Abort command key */ #define KCHAR 0x00FF /* The basic character code. */ #define KCTRL 0x0100 /* Control flag. */ #define KMETA 0x0200 /* Meta flag. */ #define KCTLX 0x0400 /* Control-X flag. */ #define KFIRST 0x0800 /* First special. fitz */ #define KLAST 0x0873 /* Last special. */ #define KRANDOM 0x0080 /* A "no key" code. */ /* * This causes the key sequence ESC [ to be delevered as * KCTRL | KMETA | KCTLX | . This allows VT100 function keys * to be bound. */ #define VT100KEY /* * These define the column used in the help (wallchart) function */ #define HFUNCCOL 3 #define HKEY 32 #define HKEYCODE 50 #define HENDCOL 55 /* * These flags, and the macros below them, * make up a do-it-yourself set of "ctype" macros that * understand the DEC multinational set, and let me ask * a slightly different set of questions. */ #define _W 0x01 /* Word. */ #define _U 0x02 /* Upper case letter. */ #define _L 0x04 /* Lower case letter. */ #define _C 0x08 /* Control. */ #define ISCTRL(c) ((cinfo[(c)]&_C)!=0) #define ISUPPER(c) ((cinfo[(c)]&_U)!=0) #define ISLOWER(c) ((cinfo[(c)]&_L)!=0) #define TOUPPER(c) ((c)-0x20) #define TOLOWER(c) ((c)+0x20) #define BUF_SIZE(wp) (wp -> w_bufp -> b_linep -> l_bp -> l_file_offset + \ wp -> w_bufp -> b_linep -> l_bp -> l_used) #define BUF_START(wp) (wp -> w_bufp -> b_linep -> l_fp -> l_file_offset) #define DOT_POS(wp) (wp -> w_dotp -> l_file_offset + wp -> w_doto) #define MARK_POS(wp) (wp -> w_markp -> l_file_offset + wp -> w_marko) #define DOT_CHAR(wp) (wp -> w_dotp -> l_text[wp -> w_doto]) #define WIND_POS(wp) (wp -> w_linep -> l_file_offset + wp -> w_loff) #define R_TYPE(wp) (wp -> w_fmt_ptr -> r_type) #define R_SIZE(wp) (wp -> w_fmt_ptr -> r_size) #define R_UNITS(wp) (wp -> w_fmt_ptr -> r_units) #define R_BYTES(wp) (wp -> w_fmt_ptr -> r_bytes) #define R_ALIGN(wp) (wp -> w_fmt_ptr -> r_align) #define R_B_PER_U(wp) (wp -> w_fmt_ptr -> r_b_per_u) #define R_CHR_PER_U(wp) (wp -> w_fmt_ptr -> r_chr_per_u) #define R_FLAGS(wp) (wp -> w_fmt_ptr -> r_flags) #define R_UNIT_FMT(wp) (wp -> w_fmt_ptr -> r_unit_fmt) #define R_POS_FMT(wp) (wp -> w_fmt_ptr -> r_pos_fmt) #define R_BYTE_FMT(wp) (wp -> w_fmt_ptr -> r_byte_fmt) #define R_POSITIONS(wp) (wp -> w_fmt_ptr -> r_positions) /* * The symbol table links editing functions * to names. Entries in the key map point at the symbol * table entry. A reference count is kept, but it is * probably next to useless right now. The old type code, * which was not being used and probably not right * anyway, is all gone. */ typedef struct SYMBOL { struct SYMBOL *s_symp; /* Hash chain. */ short s_nkey; /* Count of keys bound here. */ char *s_name; /* Name. */ bool (*s_funcp) (); /* Function. */ bits s_modify; /* modify bit */ } SYMBOL; /* * These are the legal values for 's_modify' and 'k_modify' */ #define SMOD 0x01 /* command modifies the buffer */ #define SSIZE 0x02 /* command changes buffer size */ #define SSRCH 0x04 /* command valid in search */ #define SRPLC 0x08 /* command valid in replace */ #define SBOUND 0x10 /* key was bound by user or rc file */ /* * There is a window structure allocated for * every active display window. The windows are kept in a * big list, in top to bottom screen order, with the listhead at * "wheadp". Each window contains its own values of dot and mark. * The flag field contains some bits that are set by commands * to guide redisplay; although this is a bit of a compromise in * terms of decoupling, the full blown redisplay is just too * expensive to run for every input character. */ typedef struct WINDOW { struct WINDOW *w_wndp; /* Next window */ struct BUFFER *w_bufp; /* Buffer displayed in window */ struct LINE *w_linep; /* Top line in the window */ LPOS w_loff; /* Offset into line for start pvr */ A32 w_wind_temp; /* temp storage for window file pos */ struct LINE *w_dotp; /* Line containing "." */ LPOS w_doto; /* Offset into line for "." */ A32 w_dot_temp; /* temp storage for dot file pos */ struct LINE *w_markp; /* Line containing "mark" */ LPOS w_marko; /* Byte offset for "mark" */ A32 w_mark_temp; /* temp storage for mark file pos */ char w_unit_offset; /* Byte offset for "." into unit pvr */ char w_toprow; /* Origin 0 top row of window */ char w_ntrows; /* # of rows of text in window */ bits w_flag; /* Flags. */ char w_disp_shift; /* Display byte shift; 0-3 pvr */ bool w_intel_mode; /* Display byte swaped. pvr */ struct ROW_FMT *w_fmt_ptr; /* Pointer to display format pvr */ } WINDOW; /* * Window flags are set by command processors to * tell the display system what has happened to the buffer * mapped by the window. Setting "WFHARD" is always a safe thing * to do, but it may do more work than is necessary. Always try * to set the simplest action that achieves the required update. * Because commands set bits in the "w_flag", update will see * all change flags, and do the most general one. */ #define WFFORCE 0x01 /* Force reframe. */ #define WFMOVE 0x02 /* Movement from line to line. */ #define WFEDIT 0x04 /* Editing within a line. */ #define WFHARD 0x08 /* Better to a full display. */ #define WFMODE 0x10 /* Update mode line. */ /* * This structure contains how a row is constructed. pvr */ typedef struct ROW_FMT { uchar r_type; /* format type nibbles */ uchar r_size; /* format size: must be 0,1,3,7,15, etc */ uchar r_units; /* number of units per window row: must be 1,2,4,8,16*/ uchar r_bytes; /* number of bytes per window row: must be 1,2,4,8,16*/ uchar r_align; /* number of bytes per align row: must be 1,2,4,8,16*/ uchar r_b_per_u; /* number of bytes per unit: must be 1,2,4,8,16 */ uchar r_chr_per_u; /* displayed chars per unit */ bits r_flags; /* flags controlling format */ char *r_unit_fmt; /* print format for unit */ char *r_pos_fmt; /* print format for buffer position, always a long */ char *r_byte_fmt; /* print format for bytes */ uchar *r_positions; /* list of unit positions */ struct ROW_FMT *r_srch_fmt; /* pointer to search display format */ } ROW_FMT; /* legal values for 'r_size' (values significant; used as bit mask) pvr */ #define BYTES 0x00 /* Display as byte; 8 bits */ #define WORDS 0x01 /* Display as word; 16 bits */ #define DWORDS 0x03 /* Display as long; 32 bits */ #define DOUBLES 0x07 /* Display as doubles; 64 bits */ /* legal values for 'r_type' pvr */ #define ASCII 0x10 /* Display as ascii */ #define OCTAL 0x20 /* Display as octal values */ #define DECIMAL 0x30 /* Display as decimal values */ #define HEX 0x40 /* Display as hex values */ #define BINARY 0x50 /* Display as binary values */ #define EBCDIC 0x60 /* Display as ebcdic */ #define TEXT 0x70 /* Display as normal text */ #if FLOAT_DISP #define FLOAT 0x80 /* Display as floating point number */ #endif /* * Text is kept in buffers. A buffer header, described * below, exists for every buffer in the system. The buffers are * kept in a big list, so that commands that search for a buffer by * name can find the buffer header. There is a safe store for the * dot and mark in the header, but this is only valid if the buffer * is not being displayed (that is, if "b_nwnd" is 0). The text for * the buffer is kept in a circularly linked list of lines, with * a pointer to the header line in "b_linep". */ typedef struct BUFFER { bits b_type; /* Type of buffer */ struct BUFFER *b_bufp; /* Link to next BUFFER */ struct LINE *b_dotp; /* Link to "." LINE structure */ LPOS b_doto; /* Offset of "." in above LINE */ char b_unit_offset; /* Offset into unit for "." pvr */ struct LINE *b_markp; /* The same as the above two, */ LPOS b_marko; /* but for the "mark" */ struct LINE *b_linep; /* Link to the header LINE */ char b_nwnd; /* Count of windows on buffer */ bits b_flag; /* Flags */ A32 b_begin_addr; /* File address of begining of buffer */ A32 b_end_addr; /* File address of end of buffer */ A32 b_file_size; /* Size of file */ char b_fname[NFILEN]; /* File name */ char b_bname[NBUFN]; /* Buffer name */ } BUFFER; /* Values for 'buf_type' */ #define BTFILE 0x00 /* Buffer contains a file */ #define BTDISK 0x01 /* Buffer points to a disk */ #define BTMEMORY 0x02 /* Buffer points to memory */ #define BTSAVE 0x03 /* This is the save buffer */ #define BTLIST 0x04 /* This is the buffer list */ #define BTHELP 0x05 /* This is the help buffer */ /* Values for 'b_flag' */ #define BFCHG 0x01 /* Changed. */ #define BFBAK 0x02 /* Need to make a backup. */ #define BFBAD 0x04 /* may be trashed alloc error? */ #define BFINMEM 0x08 /* File is entirely in memory */ #define BFVIEW 0x10 /* read only (jam) */ #define BFLINK 0x20 /* Linked mode pvr */ #define BFSLOCK 0x40 /* Lock buffer size pvr */ /* * This structure holds the starting position * (as a line/offset pair) and the number of characters in a * region of a buffer. This makes passing the specification * of a region around a little bit easier. * There have been some complaints that the short in this * structure is wrong; that a long would be more appropriate. * I'll await more comments from the folks with the little * machines; I have a VAX, and everything fits. */ typedef struct reg { struct LINE *r_linep; /* Origin LINE address. */ LPOS r_offset; /* Origin LINE offset. */ A32 r_size; /* Length in characters. */ } REGION; /* * All text is kept in circularly linked * lists of "LINE" structures. These begin at the * header line (which is the blank line beyond the * end of the buffer). This line is pointed to by * the "BUFFER". Each line contains a the number of * bytes in the line (the "used" size), the size * of the text array, and the text. The end of line * is not stored as a byte; it's implied. Future * additions will include update hints, and a * list of marks into the line. */ typedef struct LINE { struct LINE *l_fp; /* Link to the next line */ struct LINE *l_bp; /* Link to the previous line */ A32 l_file_offset; /* Offset from begining of file pvr */ LPOS l_size; /* Allocated size */ LPOS l_used; /* Used size */ #if PCC D8 l_text[1]; /* A bunch of characters. */ #else D8 l_text[]; /* A bunch of characters. */ #endif } LINE; /* * The rationale behind these macros is that you * could (with some editing, like changing the type of a line * link from a "LINE *" to a "REFLINE", and fixing the commands * like file reading that break the rules) change the actual * storage representation of lines to use something fancy on * machines with small address spaces. */ #define lforw(lp) ((lp)->l_fp) #define lback(lp) ((lp)->l_bp) #define lgetc(lp, n) ((lp)->l_text[(n)]&0xFF) #define lputc(lp, n, c) ((lp)->l_text[(n)]=(c)) #define llength(lp) ((lp)->l_used) /* * Externals. */ extern int thisflag; extern int lastflag; extern int curgoal; extern int epresf; extern int sgarbf; extern WINDOW *curwp; extern BUFFER *curbp; extern WINDOW *wheadp; extern BUFFER *bheadp; extern BUFFER *blistp; extern short kbdm[]; extern short *kbdmip; extern short *kbdmop; extern SYMBOL *symbol[]; extern SYMBOL *binding[]; extern BUFFER *bfind (); extern BUFFER *bcreate (); extern WINDOW *wpopup (); extern LINE *lalloc (); extern int nrow; extern int ncol; extern char version[]; extern int ttrow; extern int ttcol; extern int tceeol; extern int tcinsl; extern int tcdell; extern char cinfo[]; extern SYMBOL *symlookup (); extern int nmsg; extern int curmsgf; extern int newmsgf; extern char msg[]; /* jam */ extern char *okmsg; extern int insert_mode; extern int extend_buf; extern int flush_num; extern int auto_update; extern int flush_count; extern int rowb; extern char file_off_bad; /* * Standard I/O. */ extern char *malloc (); extern char *strcpy (); extern char *strcat (); #ifndef NOPROTO #include "prototyp.h" #endif /* NOPROTO */ beav-140/display.c0000644000175000001440000007615405667134707014101 0ustar samusers00000000000000/* * The functions in this file handle redisplay. The * redisplay system knows almost nothing about the editing * process; the editing functions do, however, set some * hints to eliminate a lot of the grinding. There is more * that can be done; the "vtputc" interface is a real * pig. The MEMMAP * changes things around for memory mapped video. With * both off, the terminal is a VT52. */ #include #include #include "def.h" D64 get_double (); D32 get_long (); D16 get_int (); void writ_echo (); void modeline (); void bin_to_text (); uint fill_buf (); uint get_currow (); uint get_curcol (); #ifndef NOPROTO struct vid; void ucopy (struct vid *vvp, struct vid *pvp); void uline (int row, struct vid *vvp, struct vid *pvp); #else void uline (); void ucopy (); #endif #if MSDOS void mem_line (int row, struct vid *vvp); #endif extern char MSG_prn_to[]; extern char MSG_disp_r_n[]; extern char MSG_11lX[]; extern char MSG_11lo[]; extern char MSG_11ld[]; extern char MSG_116e[]; extern char MSG_03o[]; extern char MSG_06o[]; extern char MSG_011lo[]; extern char MSG_03u[]; extern char MSG_05u[]; extern char MSG_010lu[]; extern char MSG_02X[]; extern char MSG_04X[]; extern char MSG_08lX[]; extern char MSG_prog_name[]; extern char MSG_disp_b_lst[]; extern char MSG_file[]; extern char MSG_RO[]; extern char MSG_WL[]; extern char MSG_RW[]; extern char MSG_AU[]; extern char MSG_NOT_AU[]; extern char MSG_curs_asc[]; extern char MSG_curs_ebc[]; extern char MSG_curs_hex[]; extern char MSG_curs_bin[]; extern char MSG_curs_dec[]; extern char MSG_curs_flt[]; extern char MSG_curs_oct[]; extern char MSG_siz_8[]; extern char MSG_siz_16[]; extern char MSG_siz_32[]; extern char MSG_siz_null[]; extern char MSG_int_shift[]; extern char MSG_mot_shift[]; extern char MSG_print1[]; extern char MSG_print2[]; extern char MSG_cnt_al_w[]; #if RUNCHK extern char ERR_disp_1[]; extern char ERR_disp_2[]; extern char ERR_disp_3[]; extern char ERR_disp_4[]; extern char ERR_disp_5[]; extern char ERR_disp_6[]; #endif extern char ebcdic_table[]; extern bool mem_map; /* * You can change these back to the types * implied by the name if you get tight for space. If you * make both of them "int" you get better code on the VAX. * They do nothing if this is not Gosling redisplay, except * for change the size of a structure that isn't used. * A bit of a cheat. */ #define XCHAR int #define XSHORT int /* * A video structure always holds * an array of characters whose length is equal to * the longest line possible. Only some of this is * used if "ncol" isn't the same as "NCOL". */ typedef struct vid { short v_hash; /* Hash code, for compares. */ short v_flag; /* Flag word. */ short v_color; /* Color of the line. */ char v_text[NCOL]; /* The actual characters. */ } VIDEO; #define VFCHG 0x0001 /* Changed. */ #define VFHBAD 0x0002 /* Hash and cost are bad. */ /* * SCORE structures hold the optimal * trace trajectory, and the cost of redisplay, when * the dynamic programming redisplay code is used. * If no fancy redisplay, this isn't used. The trace index * fields can be "char", and the score a "short", but * this makes the code worse on the VAX. */ typedef struct { XCHAR s_itrace; /* "i" index for track back. */ XCHAR s_jtrace; /* "j" index for trace back. */ XSHORT s_cost; /* Display cost. */ } SCORE; int sgarbf = TRUE; /* TRUE if screen is garbage. */ int vtrow = 0; /* Virtual cursor row. */ int vtcol = 0; /* Virtual cursor column. */ int tthue = CNONE; /* Current color. */ int ttrow = HUGE; /* Physical cursor row. */ int ttcol = HUGE; /* Physical cursor column. */ int tttop = HUGE; /* Top of scroll region. */ int ttbot = HUGE; /* Bottom of scroll region. */ char file_off_bad = FALSE; /* Have file offsets been changed */ VIDEO **vscreen; /* Edge vector, virtual. */ VIDEO **pscreen; /* Edge vector, physical. */ VIDEO *video; /* Actual screen data. */ VIDEO blanks; /* Blank line image. */ /* * Initialize the data structures used * by the display code. The edge vectors used * to access the screens are set up. The operating * system's terminal I/O channel is set up. Fill the * "blanks" array with ASCII blanks. The rest is done * at compile time. The original window is marked * as needing full update, and the physical screen * is marked as garbage, so all the right stuff happens * on the first call to redisplay. */ void vtinit () { register VIDEO *vp; register int i; /* allocate memory for screen images */ if (((vscreen = (VIDEO **) malloc (sizeof (VIDEO *) * nrow)) == NULL) || ((pscreen = (VIDEO **) malloc (sizeof (VIDEO *) * nrow)) == NULL) || ((video = (VIDEO *) malloc (sizeof (VIDEO) * 2 * nrow)) == NULL)) { err_echo (MSG_cnt_al_w); exit (1); /* can't continue */ } vp = &video[0]; for (i = 0; i < nrow; ++i) { vscreen[i] = vp; ++vp; pscreen[i] = vp; ++vp; } blanks.v_color = CTEXT; for (i = 0; i < NCOL; ++i) blanks.v_text[i] = ' '; } /* * Free memory used by the screen buffers */ void vtfree () { /* release old screen memory */ free (video); free (pscreen); free (vscreen); } /* * Tidy up the virtual display system * in anticipation of a return back to the host * operating system. Right now all we do is position * the cursor to the last line, erase the line, and * close the terminal channel. */ void vttidy () { ttcolor (CTEXT); ttnowindow (); /* No scroll window. */ ttmove (nrow - 1, 0); /* Echo line. */ tteeol (); tttidy (); ttflush (); ttclose (); } /* * Move the virtual cursor to an origin * 0 spot on the virtual display screen. I could * store the column as a character pointer to the spot * on the line, which would make "vtputc" a little bit * more efficient. No checking for errors. */ void vtmove (row, col) int row, col; { vtrow = row; vtcol = col; } /* * Write a character to the virtual display, * dealing with long lines and the display of unprintable * things like control characters. Also expand tabs every 8 * columns. This code only puts printing characters into * the virtual display image. Special care must be taken when * expanding tabs. On a screen whose width is not a multiple * of 8, it is possible for the virtual cursor to hit the * right margin before the next tab stop is reached. This * makes the tab code loop if you are not careful. * Three guesses how we found this. */ void vtputc (c) register char c; { register VIDEO *vp; vp = vscreen[vtrow]; if (vtcol >= ncol) vp->v_text[ncol - 1] = '$'; else if (ISCTRL (c) != FALSE) { vtputc ('^'); vtputc ((char) (c + 0x40)); } else { vp->v_text[vtcol] = c; vtcol++; } } /* * Write an entire screen line in the correct format. pvr * * This code only puts printing characters into * the virtual display image. * Return TRUE if something was printed to the line. */ #define REGI register bool vtputd (wp, row) WINDOW *wp; int row; /* line # to print to v screen */ { REGI VIDEO *vp; REGI uchar mode; REGI A32 row_offst; REGI uint chrs_per_row, lin_offset, i, chrs_in_lin; LINE *cur_line; static char w_buf[128]; /* temp buffer for data */ vp = vscreen[vtrow]; /* point to VIDEO structure to print into */ mode = R_TYPE (wp); /* get type of format structure */ /* get number of bytes per row */ chrs_per_row = R_BYTES (wp); /* determine the offset from begining of the buffer for this line */ row_offst = WIND_POS (wp) + (row * chrs_per_row); /* search for and point to first character in buffer to be printed */ cur_line = wp->w_linep; /* start with current first window line */ while (TRUE) { /* find line with desired character */ if (cur_line == wp->w_bufp->b_linep) { /* at end of buffer? */ return (FALSE); } if (cur_line->l_file_offset > row_offst) { /* if less than current line */ cur_line = cur_line->l_bp; /* step back */ } else if ((cur_line->l_file_offset + cur_line->l_used) <= row_offst) { cur_line = cur_line->l_fp; /* step ahead */ } else break; } lin_offset = row_offst - cur_line->l_file_offset; /* offset into line */ /* get index into the current line to start reading the current row's data */ /* copy line text into buffer */ chrs_in_lin = fill_buf (wp, cur_line, lin_offset, w_buf, chrs_per_row); /* limit line length to screen width, used in TEXT mode only */ if (chrs_in_lin > NCOL) chrs_in_lin = NCOL; /* Clear the line to spaces */ for (i = 0; i < NCOL; i++) { vp->v_text[i] = ' '; } switch (mode) { case TEXT: break; case ASCII: case EBCDIC: case BINARY: case HEX: /* print the row offset from the start of the file in HEX */ sprintf (vp->v_text, MSG_11lX, row_offst); /* to vid buf */ break; case OCTAL: /* print the row offset from the start of the file */ sprintf (vp->v_text, MSG_11lo, row_offst); /* to vid buf */ break; #if FLOAT_DISP case FLOAT: #endif case DECIMAL: /* print the row offset from the start of the file */ sprintf (vp->v_text, MSG_11ld, row_offst); /* to vid buf */ break; #if RUNCHK default: writ_echo (ERR_disp_1); break; #endif } /* print the binary data to the text line */ bin_to_text (w_buf, vp->v_text, chrs_in_lin, wp->w_fmt_ptr); vtcol = NCOL; return (TRUE); } /* * Print the contents of then binary data buffer bin_buf * into the proper mode of text into txt_buf. * Process 'len' bytes. * * input: * bin_buf pointer to buffer of binary data to process. * txt_buf pointer to output buffer to print text result into. * len length in bytes of data in bin_buf to process. * fmt_ptr pointer to a ROW_FMT to use to format the data * conversion and printing process. * output: * none. */ void bin_to_text (bin_buf, txt_buf, len, fmt_ptr) char *bin_buf, *txt_buf; uint len; ROW_FMT *fmt_ptr; { uchar i, ch, k, j, mode, size, *posn; uint temp_int; ulong temp_long; mode = fmt_ptr->r_type; /* get type of format structure */ size = fmt_ptr->r_size; /* get size of format structure */ posn = fmt_ptr->r_positions;/* pointer to array of display positions */ switch (mode) { case TEXT: case ASCII: for (i = 0; i < len; i++) { ch = bin_buf[i]; if ((ch >= ' ') && (ch < 0x7f)) txt_buf[posn[0] + i] = ch; else txt_buf[posn[0] + i] = '.'; } break; case EBCDIC: for (i = 0; i < len; i++) { txt_buf[posn[0] + i] = 0xff & ebcdic_table[0xff & bin_buf[i]]; } break; case OCTAL: switch (size) { case BYTES: /* print octal bytes */ for (i = 0; i < len; i++) { sprintf (&txt_buf[ posn[i]], MSG_03o, 0xff & bin_buf[i]); } break; case WORDS: /* print octal words */ k = 0; for (i = 0; i < len; i += 2) { temp_int = get_int (&bin_buf[i]); sprintf (&txt_buf[posn[k++]], MSG_06o, temp_int); } break; case DWORDS: /* print octal double words */ k = 0; for (i = 0; i < len; i += 4) { temp_long = get_long (&bin_buf[i]); sprintf (&txt_buf[posn[k++]], MSG_011lo, temp_long); } break; } break; case DECIMAL: switch (size) { case BYTES: /* print decimal bytes */ for (i = 0; i < len; i++) { sprintf (&txt_buf[posn[i]], MSG_03u, 0xff & bin_buf[i]); } break; case WORDS: /* print decimal words */ k = 0; for (i = 0; i < len; i += 2) { temp_int = get_int (&bin_buf[i]); sprintf (&txt_buf[posn[k++]], MSG_05u, temp_int); } break; case DWORDS: /* print decimal double words */ k = 0; for (i = 0; i < len; i += 4) { temp_long = get_long (&bin_buf[i]); sprintf (&txt_buf[posn[k++]], MSG_010lu, temp_long); } break; } break; #if FLOAT_DISP case FLOAT: { /* * The Intel floating point representation is; * bit 0 - 52 significand (53 bits) * bit 53 - 62 biased exponent (11 bits) * bit 63 sign * maximum range; 10^-308 <= X <= 10^+308 * obviously, not all patterns are legal floating point numbers. * There can be up to 16 decimal digits of significand. * There are only 3 decimal digits of exponent (308 max). */ k = 0; for (i = 0; i < len; i += sizeof (D64)) { D64 temp_d; temp_d = get_double (&bin_buf[i]); sprintf (&txt_buf[posn[k++]], MSG_116e, temp_d); } } break; #endif case HEX: switch (size) { case BYTES: /* print hex bytes and ascii chars */ for (i = 0; i < len; i++) { if ((bin_buf[i] >= ' ') && (bin_buf[i] < 0x7f)) txt_buf[posn[i + 16]] = 0xff & bin_buf[i]; else txt_buf[posn[i + 16]] = '.'; sprintf (&txt_buf[posn[i]], MSG_02X, 0xff & bin_buf[i]); } break; case WORDS: /* print hex words */ k = 0; for (i = 0; i < len; i += 2) { temp_int = get_int (&bin_buf[i]); sprintf (&txt_buf[ posn[k++]], MSG_04X, temp_int); } break; case DWORDS: /* print hex double words */ k = 0; for (i = 0; i < len; i += 4) { temp_long = get_long (&bin_buf[i]); sprintf (&txt_buf[ posn[k++]], MSG_08lX, temp_long); } break; } break; case BINARY: switch (size) { case BYTES: /* print binary bits */ for (i = 0; i < len; i++) { ch = bin_buf[i];/* get char to convert */ for (k = 0; k < 8; k++) { if (ch & 0x80) txt_buf[posn[i] + k] = '1'; else txt_buf[posn[i] + k] = '0'; ch = ch << 1; /* slide next bit into place */ } } break; case WORDS: j = 0; for (i = 0; i < len; i += 2) { temp_int = get_int (&bin_buf[i]); for (k = 0; k < 16; k++) { if (temp_int & 0x8000) txt_buf[posn[j] + k] = '1'; else txt_buf[posn[j] + k] = '0'; temp_int = temp_int << 1; /* slide next bit into place */ } j++; } break; case DWORDS: j = 0; for (i = 0; i < len; i += 4) { temp_long = get_long (&bin_buf[i]); for (k = 0; k < 32; k++) { if (temp_long & 0x80000000) txt_buf[posn[j] + k] = '1'; else txt_buf[posn[j] + k] = '0'; temp_long = temp_long << 1; /* slide next bit into place */ } j++; } break; } break; #if RUNCHK default: writ_echo (ERR_disp_2); break; #endif } len *= (fmt_ptr->r_chr_per_u + 1); /* Clean up any garbage characters left by the sprintf's */ for (i = 0; i < NCOL; i++) { if (txt_buf[i] == 0) txt_buf[i] = ' '; } } /* * Get an int from the buffer. * Perform the Intel byte shuffle if necessary */ D16 get_int (w_buf) uchar *w_buf; { int temp_int; if (curwp->w_intel_mode) { temp_int = 0xff & w_buf[1]; temp_int = temp_int << 8; temp_int |= 0xff & w_buf[0]; } else { temp_int = 0xff & w_buf[0]; temp_int = temp_int << 8; temp_int |= 0xff & w_buf[1]; } return (temp_int); } /* * Get an long from the buffer. * Perform the Intel byte shuffle if necessary */ D32 get_long (w_buf) uchar *w_buf; { long temp_long; if (curwp->w_intel_mode) { temp_long = 0xff & w_buf[3]; temp_long = temp_long << 8; temp_long |= 0xff & w_buf[2]; temp_long = temp_long << 8; temp_long |= 0xff & w_buf[1]; temp_long = temp_long << 8; temp_long |= 0xff & w_buf[0]; } else { temp_long = 0xff & w_buf[0]; temp_long = temp_long << 8; temp_long |= 0xff & w_buf[1]; temp_long = temp_long << 8; temp_long |= 0xff & w_buf[2]; temp_long = temp_long << 8; temp_long |= 0xff & w_buf[3]; } return (temp_long); } #if FLOAT_DISP /* * Get an double from the buffer. * Perform the Intel byte shuffle if necessary */ D64 get_double (w_buf) uchar *w_buf; { uchar temp_doub[sizeof (D64)]; D64 *dp; int i, siz; dp = (D64 *) temp_doub; siz = sizeof (D64); if (curwp->w_intel_mode) { for (i = 0; i <= siz - 1; i++) { temp_doub[i] = 0xff & w_buf[i]; } } else { for (i = 0; i <= 7; i++) { temp_doub[(siz - 1) - i] = 0xff & w_buf[i]; } } return (*dp); } #endif /* * Copy a length of bytes from the buffer LINEs into the designated * buffer. If the current LINE does not have enough bytes then * advance to the next. Return the actual number of bytes copied. * The number copied would be less than the number requested if * end of file is reached. */ uint fill_buf (wp, lin, lin_off, w_buff, cnt) WINDOW *wp; LINE *lin; uint lin_off, cnt; char *w_buff; { REGI uint src, dest, i; src = lin_off; /* initialize source line index */ dest = 0; /* initialize destination buffer index */ while (TRUE) { while (src < lin->l_used) { w_buff[dest++] = lin->l_text[src++]; /* copy byte */ if (dest == cnt) { /* if done */ return (cnt); /* then leave */ } } if (R_TYPE (wp) == TEXT) return (dest); /* in text mode don't advance to next line */ lin = lin->l_fp; /* move to the next line */ if (lin == wp->w_bufp->b_linep) { /* if past last line */ for (i = dest; i < cnt; ++i) w_buff[i] = 0; /* fill rest of buffer with zeros */ return (dest); /* return number of chars copied */ } src = 0; /* start next LINE at first byte */ } } /* * Erase from the end of the * software cursor to the end of the * line on which the software cursor is * located. The display routines will decide * if a hardware erase to end of line command * should be used to display this. */ void vteeol () { register VIDEO *vp; vp = vscreen[vtrow]; while (vtcol < ncol) vp->v_text[vtcol++] = ' '; } /* * Make sure that the display is * right. This is a three part process. First, * scan through all of the windows looking for dirty * ones. Check the framing, and refresh the screen. * Second, make the * virtual and physical screens the same. */ void update () { register WINDOW *wp; register VIDEO *vp1; register VIDEO *vp2; register uint i; register int hflag; hflag = FALSE; /* Not hard. */ wp = wheadp; while (wp != NULL) { /* is this window to be displayed in linked mode */ if ((curbp->b_flag & BFLINK) && (wp->w_bufp == curbp)) { /* move dot to current window's dot position */ wp->w_dotp = curwp->w_dotp; wp->w_doto = curwp->w_doto; move_ptr (wp, 0L, TRUE, TRUE, TRUE); /* insure dot is aligned */ wind_on_dot (wp); /* move window to new dot position */ } if (wp->w_flag != 0) { /* Need update. */ move_ptr (wp, 0L, FALSE, TRUE, TRUE); /* window on row boundary */ move_ptr (wp, 0L, TRUE, TRUE, TRUE); /* dot on unit boundary */ if ((wp->w_flag & WFFORCE) == 0) { wind_on_dot (wp); /* position window on dot */ } i = get_currow (wp);/* Redo this one line, mabey. */ if ((wp->w_flag & ~WFMODE) == WFEDIT) { vscreen[i]->v_color = CTEXT; vscreen[i]->v_flag |= (VFCHG | VFHBAD); vtmove (i, 0); vtputd (wp, i - wp->w_toprow); /* print line to the screen */ } else if ((wp->w_flag & ~WFMODE) == WFMOVE) { while (i < wp->w_toprow + wp->w_ntrows) { /* paint entire window */ vscreen[i]->v_color = CTEXT; vscreen[i]->v_flag |= (VFCHG | VFHBAD); vtmove (i, 0); /* print line to the screen */ if (!vtputd (wp, i - wp->w_toprow)) vteeol (); ++i; } } else if ((wp->w_flag & (WFEDIT | WFHARD)) != 0) { hflag = TRUE; i = wp->w_toprow; while (i < wp->w_toprow + wp->w_ntrows) { /* paint entire window */ vscreen[i]->v_color = CTEXT; vscreen[i]->v_flag |= (VFCHG | VFHBAD); vtmove (i, 0); /* print line to the screen */ if (!vtputd (wp, i - wp->w_toprow)) vteeol (); ++i; } } if ((wp->w_flag & WFMODE) || (wp->w_flag & WFMOVE) || (wp->w_flag & WFHARD)) modeline (wp); wp->w_flag = 0; } wp = wp->w_wndp; } if (sgarbf != FALSE) { /* Screen is garbage. */ sgarbf = FALSE; /* Erase-page clears */ epresf = FALSE; /* the message area. */ tttop = HUGE; /* Forget where you set */ ttbot = HUGE; /* scroll region. */ tthue = CNONE; /* Color unknown. */ ttmove (0, 0); tteeop (); #if MSDOS if (mem_map) { for (i = 0; i < nrow; ++i) { mem_line (i, vscreen[i]); } } else { #endif for (i = 0; i < nrow; ++i) { uline (i, vscreen[i], &blanks); ucopy (vscreen[i], pscreen[i]); } #if MSDOS } #endif ttmove (get_currow (curwp), get_curcol (curwp)); ttflush (); return; } for (i = 0; i < nrow; ++i) { /* Easy update. */ vp1 = vscreen[i]; vp2 = pscreen[i]; if ((vp1->v_flag & VFCHG) != 0) { #if MSDOS if (mem_map) mem_line (i, vp1); else #endif { uline (i, vp1, vp2); ucopy (vp1, vp2); } } } ttmove (get_currow (curwp), get_curcol (curwp)); ttflush (); } /* * Get the window relative row in which the cursor will * appear. pvr */ uint get_currow (wp) WINDOW *wp; { A32 row; /* number of bytes from start of window */ row = DOT_POS (wp) - WIND_POS (wp); /* number of rows down in window */ row /= R_BYTES (wp); row += wp->w_toprow; #if RUNCHK if (row < wp->w_toprow) printf (ERR_disp_3); if (row > (wp->w_ntrows + wp->w_toprow)) printf (ERR_disp_4); #endif return (row & 0xffff); } /* * Get the window relative column in which the cursor will * appear. pvr */ uint get_curcol (wp) WINDOW *wp; { long offset, index; uint b_per_u, pos; b_per_u = R_B_PER_U (wp); /* dot offset from start of buffer */ offset = DOT_POS (wp); offset -= wp->w_disp_shift; offset &= ~(b_per_u - 1); /* calculate mod of the current file position */ index = offset & (R_BYTES (wp) - 1); index /= b_per_u; /* limit to window width */ if (index >= NCOL) index = NCOL; pos = wp->w_fmt_ptr->r_positions[index] + wp->w_unit_offset; return (pos); } #if MSDOS void mem_line (row, vvp) int row; VIDEO *vvp; { vvp->v_flag &= ~VFCHG; /* Changes done. */ ttcolor (vvp->v_color); putline (row + 1, 1, ncol, &vvp->v_text[0]); } #endif /* * Update a saved copy of a line, * kept in a VIDEO structure. The "vvp" is * the one in the "vscreen". The "pvp" is the one * in the "pscreen". This is called to make the * virtual and physical screens the same when * display has done an update. */ void ucopy (vvp, pvp) register VIDEO *vvp; register VIDEO *pvp; { register int i; vvp->v_flag &= ~VFCHG; /* Changes done. */ pvp->v_flag = vvp->v_flag; /* Update model. */ pvp->v_hash = vvp->v_hash; pvp->v_color = vvp->v_color; for (i = 0; i < ncol; ++i) pvp->v_text[i] = vvp->v_text[i]; } /* * Update a single line. This routine only * uses basic functionality (no insert and delete character, * but erase to end of line). The "vvp" points at the VIDEO * structure for the line on the virtual screen, and the "pvp" * is the same for the physical screen. Avoid erase to end of * line when updating CMODE color lines, because of the way that * reverse video works on most terminals. */ void uline (row, vvp, pvp) int row; VIDEO *vvp; VIDEO *pvp; { register char *cp1; register char *cp2; register char *cp3; register char *cp4; register char *cp5; register int nbflag; if (vvp->v_color != pvp->v_color) { /* Wrong color, do a */ ttmove (row, 0); /* full redraw. */ ttcolor (vvp->v_color); cp1 = &vvp->v_text[0]; cp2 = &vvp->v_text[ncol]; while (cp1 != cp2) { ttputc (*cp1++); ++ttcol; } return; } cp1 = &vvp->v_text[0]; /* Compute left match. */ cp2 = &pvp->v_text[0]; while (cp1 != &vvp->v_text[ncol] && cp1[0] == cp2[0]) { ++cp1; ++cp2; } if (cp1 == &vvp->v_text[ncol]) /* All equal. */ return; nbflag = FALSE; cp3 = &vvp->v_text[ncol]; /* Compute right match. */ cp4 = &pvp->v_text[ncol]; while (cp3[-1] == cp4[-1]) { --cp3; --cp4; if (cp3[0] != ' ') /* Note non-blanks in */ nbflag = TRUE; /* the right match. */ } cp5 = cp3; /* Is erase good? */ if (nbflag == FALSE && vvp->v_color == CTEXT) { while (cp5 != cp1 && cp5[-1] == ' ') --cp5; /* Alcyon hack */ if ((int) (cp3 - cp5) <= tceeol) cp5 = cp3; } /* Alcyon hack */ ttmove (row, (int) (cp1 - &vvp->v_text[0])); ttcolor (vvp->v_color); while (cp1 != cp5) { ttputc (*cp1++); ++ttcol; } if (cp5 != cp3) /* Do erase. */ tteeol (); } /* * Redisplay the mode line for * the window pointed to by the "wp". * This is the only routine that has any idea * of how the modeline is formatted. You can * change the modeline format by hacking at * this routine. Called by "update" any time * there is a dirty window. */ void modeline (wp) register WINDOW *wp; { register char *cp, size, u_posn, *s; uchar mode; register char c; register int n; register BUFFER *bp; register A32 posn; static char posn_buf[30] = { 0 }; /* krw */ mode = wp->w_fmt_ptr->r_type; /* get type of format structure */ size = wp->w_fmt_ptr->r_size; /* get size of format structure */ n = wp->w_toprow + wp->w_ntrows; /* Location. */ vscreen[n]->v_color = CMODE;/* Mode line color. */ vscreen[n]->v_flag |= (VFCHG | VFHBAD); /* Recompute, display. */ vtmove (n, 0); /* Seek to right line. */ bp = wp->w_bufp; cp = MSG_prog_name; /* Program name. pvr */ n = 5; while ((c = *cp++) != 0) { vtputc (c); ++n; } if ((bp->b_flag & BFBAD) != 0) /* "?" if trashed. */ vtputc ('?'); else vtputc (' '); if ((bp->b_flag & BFCHG) != 0) /* "*" if changed. */ vtputc ('*'); else vtputc (' '); if (insert_mode) /* "I" if insert mode */ vtputc ('I'); else vtputc ('O'); if (bp == blistp) { /* special list */ cp = MSG_disp_b_lst; while ((c = *cp++) != 0) { vtputc (c); ++n; } goto pad; } /* Buffer name */ vtputc (' '); ++n; cp = &bp->b_bname[0]; while ((c = *cp++) != 0) { vtputc (c); ++n; } while ((int) (cp - &bp->b_bname[0]) < NBUFN) { vtputc (' '); n++; cp++; } /* File name. */ vtputc (' '); ++n; cp = MSG_file; while ((c = *cp++) != 0) { vtputc (c); ++n; } cp = &bp->b_fname[0]; while ((c = *cp++) != 0) { vtputc (c); ++n; } cp--; while ((int) (cp - &bp->b_fname[0]) < NFILE) { vtputc (' '); n++; cp++; } if (bp->b_flag & BFVIEW) s = MSG_RO; else if (bp->b_flag & BFSLOCK) s = MSG_WL; else s = MSG_RW; while (*s) { /* krw */ vtputc (*s++); ++n; } if (auto_update && !(bp->b_flag & BFVIEW) && bp->b_bname[0]) /* jam */ s = MSG_AU; else s = MSG_NOT_AU; for (; *s && n < NCOL;) { vtputc (*s++); ++n; } /* Insert current dot position into mode line. */ posn = DOT_POS (wp); u_posn = R_CHR_PER_U (wp) - wp->w_unit_offset - 1; if (u_posn < 0) u_posn = 0; switch (mode) { case TEXT: case ASCII: sprintf (posn_buf, MSG_curs_asc, posn); break; case EBCDIC: sprintf (posn_buf, MSG_curs_ebc, posn); break; case HEX: sprintf (posn_buf, MSG_curs_hex, posn, u_posn); break; case BINARY: sprintf (posn_buf, MSG_curs_bin, posn, u_posn); break; case DECIMAL: sprintf (posn_buf, MSG_curs_dec, posn, u_posn); break; #if FLOAT_DISP case FLOAT: #endif sprintf (posn_buf, MSG_curs_flt, posn, u_posn); break; case OCTAL: sprintf (posn_buf, MSG_curs_oct, posn, u_posn); break; #if RUNCHK default: writ_echo (ERR_disp_5); break; #endif } cp = posn_buf; while ((c = *cp++) != 0) { vtputc (c); ++n; } if ((mode == HEX) || (mode == DECIMAL) || (mode == OCTAL)) { switch (size) { case BYTES: sprintf (posn_buf, MSG_siz_8); break; case WORDS: sprintf (posn_buf, MSG_siz_16); break; case DWORDS: sprintf (posn_buf, MSG_siz_32); break; #if RUNCHK default: writ_echo (ERR_disp_6); break; #endif } } else sprintf (posn_buf, MSG_siz_null); cp = posn_buf; while ((c = *cp++) != 0) { vtputc (c); ++n; } if (wp->w_intel_mode) sprintf (posn_buf, MSG_int_shift, wp->w_disp_shift); else sprintf (posn_buf, MSG_mot_shift, wp->w_disp_shift); cp = posn_buf; while ((c = *cp++) != 0) { vtputc (c); ++n; } /* pad out */ pad: while (n < ncol) { vtputc (' '); ++n; } } /* * write text to the echo line */ void writ_echo (buf) char *buf; { int i; char *vpp; bool fill_spac; fill_spac = FALSE; vpp = vscreen[nrow - 1]->v_text; vscreen[nrow - 1]->v_color = CTEXT; vscreen[nrow - 1]->v_flag |= VFCHG; epresf = TRUE; for (i = 0; i < NCOL; i++) { if (buf[i] == 0) fill_spac = TRUE; if (fill_spac) vpp[i] = ' '; else vpp[i] = buf[i]; } #if MSDOS if (mem_map) { mem_line (nrow - 1, vscreen[nrow - 1]); } else #endif { uline (nrow - 1, vscreen[nrow - 1], pscreen[nrow - 1]); uline (nrow - 1, vscreen[nrow - 1], &blanks); ucopy (vscreen[nrow - 1], pscreen[nrow - 1]); ttflush (); } } /* * Print the current buffer from mark to dot using the * current window's display format. * Prompt for file name or io device to print to. */ bool print () { LINE *dot_l_sav, *mark_l_sav, *wind_l_sav; int dot_off_sav, mark_off_sav, wind_off_sav, i; char s; char fname[NFILEN]; register int nline; char buf[NFILEN], buf1[NFILEN]; /* save the original window state */ dot_l_sav = curwp->w_dotp; dot_off_sav = curwp->w_doto; mark_l_sav = curwp->w_markp; mark_off_sav = curwp->w_marko; wind_l_sav = curwp->w_linep; wind_off_sav = curwp->w_loff; /* if mark is not set then set it to location zero */ if (curwp->w_markp == NULL) { curwp->w_markp = curwp->w_bufp->b_linep->l_fp; curwp->w_marko = 0; } nline = 0; if ((s = ereply (MSG_prn_to, fname, NFILEN, NULL)) == ABORT) return (s); adjustcase (fname); if ((s = ffwopen (fname, S_IREAD | S_IWRITE)) != FIOSUC) /* Open writes message. */ return (FALSE); sprintf (buf, MSG_print1, fname); writ_echo (buf); /* make dot before mark */ if (DOT_POS (curwp) > MARK_POS (curwp)) swapmark (); /* make mark first */ while (DOT_POS (curwp) <= MARK_POS (curwp)) { /* check if we should quit */ if (ttkeyready ()) { if (ttgetc () == CTL_G) /* quit if abort was hit */ break; } nline++; /* move window so that first line is on dot */ move_ptr (curwp, DOT_POS (curwp), FALSE, TRUE, FALSE); if (vtputd (curwp, 0)) /* print line into video buffer */ { for (i = NCOL; (vscreen[vtrow]->v_text[i] < '!') || (vscreen[vtrow]->v_text[i] > '~'); i--) ; i++; if ((s = ffputline (vscreen[vtrow]->v_text, i)) != FIOSUC) break; if ((s = ffputline (MSG_disp_r_n, 2)) != FIOSUC) break; } else break; forwline (0, 1, KRANDOM); /* advance to next line */ } ffclose (); sprintf (buf1, MSG_print2, R_POS_FMT (curwp)); sprintf (buf, buf1, (long) nline); writ_echo (buf); /* restore the original window state */ curwp->w_dotp = dot_l_sav; curwp->w_doto = dot_off_sav; curwp->w_markp = mark_l_sav; curwp->w_marko = mark_off_sav; curwp->w_linep = wind_l_sav; curwp->w_loff = wind_off_sav; curwp->w_flag |= WFHARD; /* insure that window is still presentable */ return (TRUE); } beav-140/ebcdic.c0000644000175000001440000000504105667134707013630 0ustar samusers00000000000000 #include "def.h" extern char ERR_ebcdic[]; /* Function definitions */ /* This table defines the translation from EBCDIC code to ASCII. */ char ebcdic_table[] = { 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* 00-07 */ 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* 08-0F */ 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* 10-17 */ 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* 18-1F */ 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* 20-27 */ 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* 28-2F */ 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* 30-37 */ 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* 38-3F */ 0x20, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* 40-47 */ 0x2E, 0x2E, 0x2E, 0x2E, 0x3C, 0x28, 0x2B, 0x2E, /* 48-4F */ 0x26, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* 50-57 */ 0x2E, 0x2E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E, /* 58-5F */ 0x2D, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* 60-67 */ 0x2E, 0x2E, 0x7C, 0x2E, 0x25, 0x5F, 0x3E, 0x3F, /* 68-6F */ 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x27, 0x2E, 0x2E, /* 70-77 */ 0x2E, 0x60, 0x3A, 0x23, 0x40, 0x2C, 0x3D, 0x22, /* 78-7F */ 0x2E, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80-87 */ 0x68, 0x69, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* 88-8F */ 0x2E, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, /* 90-97 */ 0x71, 0x72, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* 98-9F */ 0x2E, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* A0-A7 */ 0x79, 0x7A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* A8-AF */ 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* B0-B7 */ 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* B8-BF */ 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* C0-C7 */ 0x48, 0x49, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* C8-CF */ 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, /* D0-D7 */ 0x51, 0x52, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* D8-DF */ 0x5C, 0x2E, 0X53, 0x54, 0x55, 0x56, 0x57, 0x58, /* E0-E7 */ 0x59, 0x5A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, /* E8-EF */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* F0-F7 */ 0x38, 0x39, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E /* F8-FF */ }; /* convert a ASCII character to an EBCDIC character */ char to_ebcdic (ch) char ch; { int cnt; char buf[NCOL], buf1[NCOL]; for (cnt = 0; cnt < sizeof (ebcdic_table); cnt++) { if (ch == ebcdic_table[cnt]) return (cnt); } sprintf (buf1, ERR_ebcdic, R_BYTE_FMT (curwp)); sprintf (buf, buf1, ch); writ_echo (buf); return (0); } beav-140/echo.c0000644000175000001440000001610305667134707013336 0ustar samusers00000000000000/* * Echo line reading and writing. * Common routines for reading * and writing characters in the echo line area * of the display screen. Used by the entire * known universe. */ #include "def.h" void eerase (); char ereply (); char eread (); void eformat (); void eputi (); void eputs (); void eputc (); extern char MSG_null[]; extern char MSG_y_n[]; extern char MSG_hex_dig[]; extern char MSG_hit_key[]; int epresf = FALSE; /* Stuff in echo line flag. */ /* * Erase the echo line. */ void eerase () { writ_echo (MSG_null); /* clear the echo line */ epresf = FALSE; } /* * Ask "yes" or "no" question. * Return ABORT if the user answers the question * with the abort ("^G") character. Return FALSE * for "no" and TRUE for "yes". No formatting * services are available. */ char eyesno (sp) char *sp; { register char s; char buf[NCOL]; for (;;) { s = ereply (MSG_y_n, buf, sizeof (buf), sp); if (s == ABORT) return (ABORT); if (s != FALSE) { if (buf[0] == 'y' || buf[0] == 'Y') return (TRUE); if (buf[0] == 'n' || buf[0] == 'N') return (FALSE); } } } /* * Write out a prompt, and read back a * reply. The prompt is now written out with full "eprintf" * formatting, although the arguments are in a rather strange * place. This is always a new message, there is no auto * completion, and the return is echoed as such. */ /* VARARGS3 */ char ereply (fp, buf, nbuf, arg) char *fp; char *buf; int nbuf; char *arg; { return (eread (fp, buf, nbuf, EFNEW | EFCR, arg)); } /* * This is the general "read input from the * echo line" routine. The basic idea is that the prompt * string "prompt" is written to the echo line, and a one * line reply is read back into the supplied "buf" (with * maximum length "len"). The "flag" contains EFNEW (a * new prompt), an EFAUTO (autocomplete), or EFCR (echo * the carriage return as CR). */ char eread (fp, buf, nbuf, flag, ap) char *fp; char *buf; char *ap; int nbuf, flag; { register int cpos; register SYMBOL *sp1; register SYMBOL *sp2; register int i; register int c; register int h; register int nhits; register int nxtra; register int bxtra; int quote_flag; quote_flag = 0; cpos = 0; if (kbdmop != NULL) { /* In a macro. */ while ((c = *kbdmop++) != '\0') buf[cpos++] = c; buf[cpos] = '\0'; goto done; } if ((flag & EFNEW) != 0 || ttrow != nrow - 1) { ttcolor (CTEXT); ttmove (nrow - 1, 0); epresf = TRUE; } else eputc (' '); eformat (fp, ap); tteeol (); ttflush (); for (;;) { c = getkey (); if (c == ' ' && (flag & EFAUTO) != 0) { nhits = 0; nxtra = HUGE; for (h = 0; h < NSHASH; ++h) { sp1 = symbol[h]; while (sp1 != NULL) { for (i = 0; i < cpos; ++i) { if (buf[i] != sp1->s_name[i]) break; } if (i == cpos) { if (nhits == 0) sp2 = sp1; ++nhits; bxtra = getxtra (sp1, sp2, cpos); if (bxtra < nxtra) nxtra = bxtra; } sp1 = sp1->s_symp; } } if (nhits == 0) /* No completion. */ continue; for (i = 0; i < nxtra && cpos < nbuf - 1; ++i) { c = sp2->s_name[cpos]; buf[cpos++] = c; eputc (c); } ttflush (); if (nhits != 1) /* Fake a CR if there */ continue; /* is 1 choice. */ c = (KCTRL | 'M'); } if (quote_flag) { c = c & 0x1f; quote_flag = 0; } switch (c) { case (KCTRL | 'Q'): quote_flag = 1; break; case (KCTRL | 'M'): /* Return, done. */ case (KCTRL | 'J'): /* Linefeed, done. */ buf[cpos] = '\0'; if (kbdmip != NULL) { if (kbdmip + cpos + 1 > &kbdm[NKBDM - 3]) { (void) ctrlg (FALSE, 0, KRANDOM); ttflush (); return (ABORT); } for (i = 0; i < cpos; ++i) *kbdmip++ = buf[i]; *kbdmip++ = '\0'; } if ((flag & EFCR) != 0) { ttputc (0x0D); ttflush (); } goto done; case (KCTRL | 'G'): /* Bell, abort. */ eputc (0x07); (void) ctrlg (FALSE, 0, KRANDOM); ttflush (); return (ABORT); case 0x7F: /* Rubout, erase. */ case (KCTRL | 'H'): /* Backspace, erase. */ if (cpos != 0) { ttputc ('\b'); ttputc (' '); ttputc ('\b'); --ttcol; if (ISCTRL (buf[--cpos]) != FALSE) { ttputc ('\b'); ttputc (' '); ttputc ('\b'); --ttcol; } ttflush (); } break; case (KCTRL | 'U'): /* C-U, kill line. */ while (cpos != 0) { ttputc ('\b'); ttputc (' '); ttputc ('\b'); --ttcol; if (ISCTRL (buf[--cpos]) != FALSE) { ttputc ('\b'); ttputc (' '); ttputc ('\b'); --ttcol; } } ttflush (); break; default: /* All the rest. */ if ((cpos < nbuf - 1) && ((c & ~KCHAR) == 0)) { buf[cpos++] = c; eputc (c); ttflush (); } } /* End switch */ } done: if (buf[0] == '\0') return (FALSE); return (TRUE); } /* * The "sp1" and "sp2" point to extended command * symbol table entries. The "cpos" is a horizontal position * in the name. Return the longest block of characters that can * be autocompleted at this point. Sometimes the two symbols * are the same, but this is normal. */ int getxtra (sp1, sp2, cpos) SYMBOL *sp1; SYMBOL *sp2; int cpos; { register int i; i = cpos; for (;;) { if (sp1->s_name[i] != sp2->s_name[i]) break; if (sp1->s_name[i] == '\0') break; ++i; } return (i - cpos); } /* * Printf style formatting. This is * called by both "eprintf" and "ereply", to provide * formatting services to their clients. The move to the * start of the echo line, and the erase to the end of * the echo line, is done by the caller. */ void eformat (fp, ap) char *fp; char *ap; { register int c; while ((c = *fp++) != '\0') { if (c != '%') eputc (c); else { c = *fp++; switch (c) { case 'd': eputi (*(int *) ap, 10); ap += sizeof (int); break; case 'x': /* krw */ eputi (*(int *) ap, 16); ap += sizeof (int); break; case 'o': eputi (*(int *) ap, 8); ap += sizeof (int); break; case 's': eputs (ap); ap += sizeof (char *); break; default: eputc (c); } } } } /* * Put integer, in radix "r". */ void eputi (i, r) int i; int r; { static char *convert = { MSG_hex_dig }; register int q; if ((q = i / r) != 0) eputi (q, r); eputc (convert[i % r]); } /* * Put string. */ void eputs (s) char *s; { register int c; while ((c = *s++) != '\0') eputc (c); } /* * Put character. Watch for * control characters, and for the line * getting too long. */ void eputc (c) int c; { if (ttcol < ncol) { if (ISCTRL (c) != FALSE) { eputc ('^'); c ^= 0x40; } ttputc (c); ++ttcol; } } /* * Print warning message and wait for the user to hit a key. */ void err_echo (buf) char *buf; { char ch[NCOL * 2]; strcpy (ch, buf); strcat (ch, MSG_hit_key); writ_echo (ch); ttbeep (); while (ttgetc () != CTL_G); { ttbeep (); ttflush (); } } beav-140/english.c0000644000175000001440000003052505667134707014055 0ustar samusers00000000000000/* * This file contains all English language text srtings */ #include "def.h" /* in basic.c */ char MSG_mark_set[] = "Mark set"; char MSG_no_mark[] = "No mark in this window"; char MSG_go_b_n[] = "Goto byte number: "; char MSG_bad_num[] = "ERROR: Bad number"; /* in buffer.c */ char MSG_use_b[] = "Enter name of buffer to goto: "; char MSG_kill_b[] = "Enter name of buffer to delete: "; char MSG_no_del_m[] = "ERROR: Can't delete 'main'"; char MSG_buf_disp[] = "ERROR: Buffer is displayed - continue"; char MSG_main[] = "main"; char MSG_l_buf_h[] = "S T Size Buffer File"; char MSG_l_buf_h1[] = "- - ------ ------ ----"; char MSG_no_chg[] = "Discard changes"; char MSG_yank_b[] = "Yank from buffer: "; char MSG_no_buf[] = "ERROR: no such buffer"; char MSG_no_s_yank[] = "ERROR: can't yank to self!"; char MSG_buf_nam[] = "Buffer name: "; char MSG_bad_l[] = "ERROR: Bad line!"; char MSG_pick[] = "%s: G(oto) or K(ill) S(ave) "; char MSG_siz_chg[] = "Current buffer size may be changed"; char MSG_no_siz_chg[] = "Current buffer size is locked"; char MSG_cnt_al_b[] = "ERROR: Cannot allocate BUFFER block"; char MSG_ins_cnt[] = "Insert %s bytes, Hit Ctl-G to quit."; /* in display.c */ char MSG_prn_to[] = "Print to: "; char MSG_prog_name[] = "BEAV"; char MSG_disp_b_lst[] = " Buffer List "; char MSG_file[] = "File: "; char MSG_RO[] = " [RO]"; char MSG_WL[] = " [WL]"; char MSG_RW[] = " [RW]"; char MSG_AU[] = "[AU]"; char MSG_NOT_AU[] = " "; char MSG_curs_asc[] = "CURSOR=%08lX, ASCII"; char MSG_curs_ebc[] = "CURSOR=%08lX, EBCDIC"; char MSG_curs_hex[] = "CURSOR=%08lX,%2X HEX"; char MSG_curs_bin[] = "CURSOR=%08lX,%2X BIN"; char MSG_curs_dec[] = "CURSOR=%08lu,%2u DEC"; char MSG_curs_flt[] = "CURSOR=%08lu,%2u FLOAT"; char MSG_curs_oct[] = "CURSOR=%08lo,%2o OCTAL"; char MSG_print1[] = "Writing: %s; Hit Ctl-G to quit"; char MSG_print2[] = "Wrote %s lines"; char MSG_cnt_al_v[] = "ERROR: Cannot allocate memory fot VIDEO"; /* in ebcdic.c */ #if RUNCHK char ERR_ebcdic[] = "ERROR: Character %s not found in EBCDIC table\n"; #endif /* in echo.c */ char MSG_y_n[] = "%s [y/n]? "; char MSG_hit_key[] = " Hit Ctl-G to continue"; /* in extend.c */ char MSG_not_now[] = "Not now"; char MSG_func[] = "Function: "; char MSG_unk_func[] = "ERROR: Unknown function for binding"; char MSG_cmd_t_ex[] = "Command to execute: "; char MSG_unk_ext[] = "ERROR: Unknown extended command"; char MSG_unk_rc[] = "ERROR: Unknown rc command: "; char MSG_d_b[] = "Display key binding for which key? (hit key now!)"; char MSG_unbd[] = "%s is unbound"; char MSG_bnd_to[] = "%s is bound to %s"; char MSG_ins_self[] = "ins-self"; char MSG_bnd_file[] = "Binding file: "; char MSG_bld_wall[] = "Building help buffer"; char MSG_wall_head[] = "# Function name Key binding Key code"; char MSG_beavrc[] = "beavrc"; /* in file.c */ char MSG_rd_file[] = "Read file: "; char MSG_trash[] = "#tempbuf#"; char MSG_ins_file[] = "Insert file: "; char MSG_not_fnd[] = "Not found"; char MSG_visit[] = "Visit file: "; char MSG_view[] = "View file (read only): "; char MSG_buf_ex[] = "ERROR: Buffer exists"; char MSG_old_buf[] = "ERROR: Old buffer"; char MSG_cnt_cr[] = "ERROR: Cannot create buffer"; char MSG_reading[] = "reading <%s>"; char MSG_read_lx[] = "Read %s bytes, Hit Ctl-G to quit."; char MSG_no_mem_rd[] = "ERROR: Insufficient memory, buffer set to read only"; char MSG_wr_file[] = "Write file: "; char MSG_no_fn[] = "ERROR: No file name"; char MSG_bk_err[] = "ERROR: Backup error, save anyway"; char MSG_writing[] = "writing <%s>"; char MSG_wrot_n[] = "Wrote %s bytes, Hit Ctl-G to quit."; char MSG_fil_nam[] = "File name: "; #if RUNCHK char ERR_parse_fn[] = "ERROR: Starting address (%s) must preceede ending address (%s)"; char ERR_addr_neg[] = "ERROR: Addresses cannot be negative"; char ERR_f_size[] = "ERROR: Cannot access past end of file. (file size = %s)"; #endif /* in fileio.c */ char MSG_cnt_wr[] = "ERROR: Cannot open file for writing"; char MSG_wr_io_er[] = "ERROR: Write I/O error"; char MSG_rd_er[] = "ERROR: File read error"; #if UNIX char MSG_bak[] = ".~"; #else char MSG_bak[] = ".bak"; #endif char MSG_backup[] = "Back-up of %s to %s"; char MSG_back_er[] = "ERROR: Back-up of %s to %s FAILED !!"; char MSG_back_of[] = "%s - Back-up of <%s> to <%s>\n"; /* in kbd.c */ char MSG_tab[] = "Tab"; char MSG_ret[] = "Return"; char MSG_bksp[] = "Backspace"; char MSG_space[] = "Space"; char MSG_rubout[] = "Rubout"; /* in line.c */ char MSG_cnt_alloc[] = "ERROR: Cannot allocate %s bytes for a line"; char MSG_save_buf[] = "save-buffer"; /* in main.c */ char MSG_ok[] = "ok"; char MSG_no_mod[] = "ERROR: Buffer can not be modified"; char MSG_no_s_chg[] = "ERROR: Buffer size can not be changed"; char MSG_auto_fl[] = "Doing auto buffer flush"; char MSG_quit[] = "quit-no-save"; char MSG_st_mac[] = "Start macro"; char MSG_end_mac[] = "End macro"; char MSG_num_mod[] = "Number of modifcations per update: "; char version[] = "BEAV, Ver 1.40, March 31, 1993"; /* in random.c */ char MSG_sh_pos[] = "Cursor: %s, Mark: %s, Buffer Size: %s, File Size: %s"; char MSG_sh_pos1[] = "Cursor: %s, No Mark, Buffer Size: %s, File Size: %s"; char MSG_f_str[] = ", File: <%s>"; char MSG_lnk[] = "All windows on buffer <%s> are %s"; char MSG_unlink[] = "unlinked"; char MSG_link[] = "linked"; char MSG_bad_key[] = "ERROR: bad key = "; char MSG_esc[] = "Esc,"; char MSG_ctl_x[] = "Ctl-X,"; char MSG_ctl[] = "Ctl-"; char MSG_fn[] = "FN,"; char MSG_w_not_empty[] = "Destination buffer must be empty and modifiable"; char MSG_procing[] = "Processing at %s, Hit Ctl-G to quit."; char MSG_edit_float[] = "ERROR: Cannot edit floating point display."; /* in region.c */ char MSG_sv_in_b[] = "Save in buffer: "; char MSG_sav_slf[] = "ERROR: Can't save to self!"; /* in search.c */ char MSG_sch_str[] = " Search String"; char MSG_bsrc_str[] = "Back Search String"; char MSG_rpl_str[] = "Replace String"; char MSG_pat_fnd[] = "Pattern found at %s"; char MSG_no_srch[] = "ERROR: No last search"; char MSG_fnd_at[] = "Found at %s, (R)eplace, (S)kip, (A)ll, (O)ne, (Q)uit."; char MSG_no_rpl[] = "No replacements done"; char MSG_1_rpl[] = "1 replacement done"; char MSG_n_rpl[] = "%s replacements done"; char MSG_srcing[] = "Searching at %s, Hit Ctl-G to quit."; char MSG_curs[] = "%s; Curs = %s, %s Len = %s => "; char MSG_cmp_end[] = "Compare reached the end of a buffer"; char MSG_cmp_term[] = "Compare terminated by user"; char MSG_cmp_dif[] = "Difference is detected at the two cursor positions"; char MSG_only_2[] = "ERROR: There must be exactly two windows displayed to use Compare"; char MSG_cmping[] = "Comparing at %s, Hit Ctl-G to quit."; /* in spawn.c */ char MSG_shell[] = "COMSPEC"; char MSG_def_shell[] = "/command.com"; char MSG_pmpt[] = "PROMPT=[BEAV]"; char MSG_pt[] = "PROMPT"; char MSG_pme[] = "PROMPT="; /* in symbol.c */ char MSG_byte_shift[] = "display-byte-shift"; char MSG_back_char[] = "move-back-char"; char MSG_forw_del_char[] = "delete-forw-char"; char MSG_toggle_swap[] = "display-swap-order"; char MSG_forw_char[] = "move-forw-char"; char MSG_abort[] = "abort-cmd"; char MSG_back_del_char[] = "delete-back-char"; char MSG_refresh[] = "refresh-screen"; char MSG_forw_line[] = "move-forw-line"; char MSG_back_line[] = "move-back-line"; char MSG_quote[] = "insert-literally"; char MSG_recall[] = "recall-srch-string"; char MSG_twiddle[] = "unit-twiddle"; char MSG_forw_page[] = "move-forw-page"; char MSG_kill_region[] = "delete-mark-to-cursor"; char MSG_yank[] = "yank"; char MSG_down_window[] = "move-window-down"; char MSG_ins_toggle[] = "insert-toggle"; char MSG_display_buffers[] = "buffers-display"; char MSG_exit_flush_all[] = "quit-save-all"; char MSG_set_file_name[] = "buffer-set-file-name"; char MSG_file_insert[] = "insert-file"; char MSG_buf_size_lock[] = "buffer-size-lock"; char MSG_flush_all[] = "save-all-buffers"; char MSG_up_window[] = "move-window-up"; char MSG_file_read[] = "file-read"; char MSG_file_save[] = "file-save"; char MSG_file_visit[] = "file-visit"; char MSG_file_write[] = "file-write"; char MSG_swap_dot_and_mark[] = "swap-cursor-and-mark"; char MSG_shrink_window[] = "window-shrink"; char MSG_display_position[] = "show-position"; char MSG_start_macro[] = "macro-start"; char MSG_end_macro[] = "macro-end"; char MSG_help[] = "binding-for-key"; char MSG_only_window[] = "window-single"; char MSG_del_window[] = "window-delete"; char MSG_split_window[] = "window-split"; char MSG_scr_row[] = "screen-rows"; char MSG_use_buffer[] = "change-buffer"; char MSG_spawn_cli[] = "spawn-shell"; char MSG_execute_macro[] = "macro-execute"; char MSG_goto_line[] = "move-to-byte"; char MSG_ins_unit[] = "insert-unit"; char MSG_kill_buffer[] = "kill-buffer"; char MSG_load_bindings[] = "bindings-load"; char MSG_forw_window[] = "change-window-forw"; char MSG_back_window[] = "change-window-back"; char MSG_view_file[] = "file-view"; char MSG_enlarge_window[] = "window-enlarge"; char MSG_ascii_mode[] = "display-ascii"; char MSG_binary_mode[] = "display-binary"; char MSG_n_combine[] = "n-way-combine"; char MSG_buffer_name[] = "buffer-set-name"; char MSG_decimal_mode[] = "display-decimal"; char MSG_ebcdic_mode[] = "display-ebcdic"; char MSG_float_mode[] = "display-float"; char MSG_hex_mode[] = "display-hex"; char MSG_back_del_unit[] = "delete-back-unit"; char MSG_octal_mode[] = "display-octal"; char MSG_n_split[] = "n-way-split"; char MSG_display_version[] = "show-version"; char MSG_show_save_buf[] = "show-save-buf"; char MSG_unit_size1[] = "display-bytes"; char MSG_unit_size2[] = "display-words"; char MSG_unit_size4[] = "display-double-words"; char MSG_reposition_window[] = "window-reposition"; char MSG_set_mark[] = "mark-set"; char MSG_goto_eob[] = "move-to-end"; char MSG_goto_bob[] = "move-to-begining"; char MSG_next_buff[] = "change-to-next-buffer"; char MSG_prev_buff[] = "change-to-prev-buffer"; char MSG_query_replace[] = "replace"; char MSG_display_bindings[] = "help"; char MSG_auto_save[] = "auto-save"; char MSG_back_unit[] = "move-back-unit"; char MSG_compare[] = "compare"; char MSG_forw_del_unit[] = "delete-forw-unit"; char MSG_forw_unit[] = "move-forw-unit"; char MSG_link_windows[] = "window-link"; char MSG_print[] = "print-mark-to-cursor"; char MSG_back_search[] = "search-back"; char MSG_forw_search[] = "search-forw"; char MSG_back_page[] = "move-back-page"; char MSG_copy_region[] = "copy-mark-to-cursor"; char MSG_extended_command[] = "extended-command"; char MSG_search_again[] = "search-again"; char MSG_bind_to_key[] = "bind-to-key"; char MSG_file_visit_split[] = "file-visit-split"; char MSG_yank_buffer[] = "yank-buffer"; char MSG_save_region[] = "save-mark-to-cursor"; char MSG_use_buffer_split[] = "move-to-buffer-split"; char MSG_no_f_tb[] = "ERROR: Could not find <%s> in look up table\n"; /* in ttykbd.c */ char MSG_sp_key[] = "%u special keys bound\n"; /* in window.c */ char MSG_no_splt[] = "ERROR: Cannot split a %s line window"; char MSG_cnt_al_w[] = "ERROR: Cannot allocate WINDOW block"; char MSG_one_w[] = "ERROR: Only one window"; char MSG_imp_chg[] = "ERROR: Impossible change"; char MSG_scrn_rows[] = "Number of screen rows: "; #if RUNCHK /* in basic.c */ char ERR_bas_1[] = "ERROR: unknown r_type in basic #1"; /* in display.c */ char ERR_disp_1[] = "ERROR: unknown r_type in display #1"; char ERR_disp_2[] = "ERROR: unknown r_type in display #2"; char ERR_disp_3[] = "ERROR: row less than zero\n"; char ERR_disp_4[] = "ERROR: row greater then window size\n"; char ERR_disp_5[] = "ERROR: unknown r_type in display #3"; char ERR_disp_6[] = "ERROR: unknown r_size in display "; /* in line.c */ char ERR_no_alloc[] = "ERROR: new line was allocated during read pattern\n"; char ERR_db_dalloc[] = "ERROR: line was deallocated during read pattern\n"; char ERR_lock[] = "ERROR: This is size locked, cannot insert."; char ERR_lock_del[] = "ERROR: This is size locked, cannot delete."; /* in random.c */ char ERR_rnd_1[] = "ERROR: unknown r_type in random #1"; char ERR_rnd_2[] = "ERROR: unknown r_size in random #2"; char ERR_rnd_3[] = "ERROR: unknown r_type in random #3"; char ERR_rnd_4[] = "ERROR: unknown r_size in random #4"; char ERR_rnd_5[] = "ERROR: unknown r_size in random #5"; char ERR_rnd_6[] = "ERROR: unknown r_size in random #6"; char ERR_rnd_7[] = "ERROR: unknown r_size in random #7"; /* in search.c */ char ERR_rdpat[] = "ERROR: bad r_type in readpattern\n"; char ERR_mask[] = "ERROR: size of mask pattern, pat=%d, mask=%d\n"; char ERR_m_cl[] = "ERROR: in ascii mode mask byte was not cleared\n"; /* in ttyio.c */ char ERR_bd_pl[] = "ERROR: bad call to putline\n"; #endif beav-140/extend.c0000644000175000001440000002717305667134707013720 0ustar samusers00000000000000/* * Extended (M-X) commands. */ #include "def.h" extern char MSG_not_now[]; extern char MSG_func[]; extern char MSG_unk_func[]; extern char MSG_cmd_t_ex[]; extern char MSG_unk_ext[]; extern char MSG_d_b[]; extern char MSG_unbd[]; extern char MSG_bnd_to[]; extern char MSG_ins_self[]; extern char MSG_bnd_file[]; extern char MSG_bld_wall[]; extern char MSG_wall_head[]; extern char MSG_beavrc[]; extern char MSG_null[]; extern char MSG_extended_command[]; extern char MSG_unk_rc[]; #ifdef CUSTOMIZE char *flook (); static char *bindnm = { 0 }; /* file name for customized key bindings */ #endif /* * This function modifies the keyboard * binding table, by adjusting the entries in the * big "bindings" array. Most of the grief deals with the * prompting for additional arguments. This code does not * work right if there is a keyboard macro floating around. * Should be fixed. */ bool bindtokey () { register int s; register SYMBOL *sp; register int c; char xname[NXNAME]; #ifdef CUSTOMIZE char xname2[NXNAME]; #endif if (kbdmip != NULL || kbdmop != NULL) { writ_echo (MSG_not_now); return (FALSE); } if ((s = eread (MSG_func, xname, NXNAME, EFAUTO, NULL)) != TRUE) return (s); if ((sp = symlookup (xname)) == NULL) { writ_echo (MSG_unk_func); return (FALSE); } #ifdef CUSTOMIZE strcpy (xname2, xname); #endif eputc (' '); eputc ('K'); eputc ('e'); eputc ('y'); eputc (':'); eputc (' '); ttflush (); c = getkey (); /* Read key. */ keyname (xname, c); /* Display keyname. */ eputs (xname); ttflush (); if (binding[c] != NULL) /* Unbind old, and */ --binding[c]->s_nkey; binding[c] = sp; /* rebind new. */ ++sp->s_nkey; sp->s_modify |= SBOUND; /* flag as altered key binding */ return (TRUE); } /* * Extended command. Call the message line * routine to read in the command name and apply autocompletion * to it. When it comes back, look the name up in the symbol table * and run the command if it is found and has the right type. * Print an error if there is anything wrong. */ char extend (f, n, k) int f, n, k; { register SYMBOL *sp; register char s; char xname[NXNAME]; if ((s = eread (MSG_cmd_t_ex, xname, NXNAME, EFNEW | EFAUTO, NULL)) != TRUE) return (s); if ((sp = symlookup (xname)) != NULL) return ((*sp->s_funcp) (f, n, KRANDOM)); writ_echo (MSG_unk_ext); return (ABORT); } /* * Read a key from the keyboard, and look it * up in the binding table. Display the name of the function * currently bound to the key. Say that the key is not bound * if it is indeed not bound, or if the type is not a * "builtin". This is a bit of overkill, because this is the * only kind of function there is. */ bool help () { register SYMBOL *sp; register int c; char b[20]; char buf[80]; writ_echo (MSG_d_b); c = getkey (); keyname (b, c); if ((sp = binding[c]) == NULL) { sprintf (buf, MSG_unbd, b); writ_echo (buf); } else { sprintf (buf, MSG_bnd_to, b, sp->s_name); writ_echo (buf); } return (TRUE); } /* * Sort the lines in the buffer. */ void sort_buf (b_ptr, cnt) BUFFER *b_ptr; int cnt; { LINE *lp1, *lp2; bool no_swap; int loop1, loop2; for (loop1 = cnt; loop1 > 0; loop1--) { no_swap = TRUE; lp1 = b_ptr->b_linep->l_fp; /* point to first line */ lp2 = lp1->l_fp; /* point to next line */ for (loop2 = 0; loop2 <= loop1; loop2++) { /* compare strings and swap if necessary */ if (0 < strcmp (&lp1->l_text[HFUNCCOL], &lp2->l_text[HFUNCCOL])) { lp1->l_bp->l_fp = lp2; /* get pointer to first string */ lp2->l_fp->l_bp = lp1; /* make it point to second string */ lp1->l_fp = lp2->l_fp; lp2->l_bp = lp1->l_bp; lp1->l_bp = lp2; lp2->l_fp = lp1; lp2->l_file_offset = lp1->l_file_offset; lp1->l_file_offset = lp2->l_file_offset + lp2->l_used; no_swap = FALSE; } else { /* if no swap then advance both pointers */ lp1 = lp2; } lp2 = lp1->l_fp; } /* quick exit if sort is finished sooner than expected */ if (no_swap) { return; } } } /* * This function creates a table, listing all * of the command keys and their current bindings, and stores * the table in the standard pop-op buffer (the one used by the * directory list command, the buffer list command, etc.). This * lets the editor produce it's own wall chart. The bindings to * "ins-self" are only displayed if there is an argument. */ char wallchart (f, n, k) int f, n, k; { register char s; register int key, i, j; register SYMBOL *sp; register char *cp1; register char *cp2; char buf[64]; WINDOW *wp; if ((s = bclear (blistp)) != TRUE) /* Clear it out. */ return (s); i = 0; (void) strcpy (blistp->b_fname, MSG_null); blistp->b_flag = BFVIEW; blistp->b_type = BTHELP; writ_echo (MSG_bld_wall); sprintf (buf, MSG_wall_head); if (addline (buf) == FALSE) return (FALSE); for (key = 0; key < NKEYS; ++key) { /* For all keys. */ sp = binding[key]; if (sp != NULL && (f != FALSE || strcmp (sp->s_name, MSG_ins_self) != 0)) { cp1 = &buf[0]; while (cp1 < &buf[HFUNCCOL]) /* Goto column 3. */ *cp1++ = ' '; if ((sp->s_modify & SBOUND) == 0) /* comment out default binding */ buf[0] = '#'; cp2 = sp->s_name; /* Add function name. */ while (*cp1++ = *cp2++) ; cp1--; while (cp1 < &buf[HKEY]) /* Goto column 32. */ *cp1++ = ' '; keyname (&buf[HKEY], key); cp1 = &buf[strlen (buf)]; while (cp1 < &buf[HKEYCODE]) /* Goto column 50. */ *cp1++ = ' '; sprintf (&buf[HKEYCODE], "%4X", key); if (addline (buf) == FALSE) break; /* lets go with what we have */ i++; } } /* list unbound functions lest they get lost */ for (j = 0; j < NSHASH; j++) { sp = symbol[j]; while (sp != NULL) { if (sp->s_nkey == 0) { cp1 = &buf[0]; while (cp1 < &buf[HFUNCCOL]) /* Goto column 3. */ *cp1++ = ' '; buf[0] = '#'; cp2 = sp->s_name; /* Add function name. */ while (*cp1++ = *cp2++) ; cp1--; while (cp1 < &buf[HENDCOL]) *cp1++ = ' '; *cp1 = 0; i++; if (addline (buf) == FALSE) break; /* lets go with what we have */ } sp = sp->s_symp; } } sort_buf (blistp, i); /* sort buffer lines */ popblist (); writ_echo (MSG_null); /* make new window the current window */ wp = wheadp; while (wp != NULL) { if (wp->w_bufp == blistp) { curwp = wp; curbp = wp->w_bufp; return (TRUE); } wp = wp->w_wndp; } return (TRUE); } /* check for RC file and read it in if found * - also, set local file variable for bindtokey for saving new defs * (this is some what of a hack as it only handles 'bindtokey' changes at * this time - also local file io !!!) */ void check_extend (sfname) char *sfname; /* name of startup file (null if default) */ { char *fname; /* resulting file name to execute */ char rc_name[NFILEN]; /* fixed up name of rc file */ char *term; char *getenv (); register SYMBOL *sp; char funcname[NXNAME + 1]; char keybind[NXNAME + 1]; int keyval; FILE *bindf; /* look up the startup file */ if ((sfname != NULL) && (*sfname != 0)) fname = flook (sfname, TRUE); else { #ifdef UNIX /* hidden file under unix */ strcpy (&rc_name[0], "."); strcpy (&rc_name[1], MSG_beavrc); if ((term = getenv ("TERM")) != 0) { strcpy (&rc_name[strlen (rc_name)], "."); strcpy (&rc_name[strlen (rc_name)], term); } fname = flook (rc_name, TRUE); /* if fixed up name is not there then check original */ if (fname == NULL) { /* hidden file under unix */ strcpy (&rc_name[0], "."); strcpy (&rc_name[1], MSG_beavrc); fname = flook (rc_name, TRUE); } #else strcpy (rc_name, MSG_beavrc); fname = flook (rc_name, TRUE); #ifdef AMIGA /* look for .beavrc in the current directory */ if (!fname) { rc_name[0] = '.'; strcpy (&rc_name[1], MSG_beavrc); fname = flook (rc_name, TRUE); } /* look for .beavrc in S: */ if (!fname) { /* Have a look in startup directory */ rc_name[0] = 'S'; rc_name[1] = ':'; rc_name[2] = '.'; strcpy (&rc_name[3], MSG_beavrc); fname = flook (rc_name, TRUE); } #endif /* AMIGA */ #endif } /* if it isn't around, don't sweat it */ if (fname == NULL) return; if (bindf = fopen (fname, "r")) { char buffr[80]; char *buffp; buffp = buffr; while (fread (buffp++, sizeof (char), 1, bindf) == 1) { /* scanf is unhappy with commas */ if (buffp[-1] == ',') buffp[-1] = '-'; /* did we get a whole line */ if (buffp[-1] == '\n') { *buffp = 0; /* terminate line */ buffp = buffr; sscanf (buffr, "%s %s %x", funcname, keybind, &keyval); if ((buffr[0] == '#') || (keyval == 0)) continue; /* check if this is a command to execute */ if ((strcmp (funcname, MSG_extended_command) == 0) && (keybind[0] > 'Z')) { if ((sp = symlookup (keybind)) != NULL) (*sp->s_funcp) (TRUE, keyval, KRANDOM); else { char temp_b[40]; sprintf (temp_b, "%s %s", MSG_unk_rc, keybind); writ_echo (temp_b); } } else { if (sp = symlookup (funcname)) { if (binding[keyval] != NULL) /* Unbind old, and */ --binding[keyval]->s_nkey; binding[keyval] = sp; /* rebind new. */ ++sp->s_nkey; sp->s_modify |= SBOUND; /* flag as altered key binding */ } } } } fclose (bindf); } } /* Look up the existance of a file along the normal or PATH environment variable. Look first in the HOME directory if asked and possible */ char * flook (fname, hflag) char *fname; /* base file name to search for */ int hflag; /* Look in the HOME environment variable first? */ { register char *home; /* path to home directory */ register char *path; /* environmental PATH variable */ register char *sp; /* pointer into path spec */ register int i; /* index */ static char fspec[NFILEN * 2]; /* full path spec to search */ char *getenv (); FILE *bindf; if (hflag) { home = getenv ("HOME"); if (home != NULL) { /* build home dir file spec */ strcpy (fspec, home); if (fspec[strlen (fspec) - 1] != '/') strcat (fspec, "/"); strcat (fspec, fname); /* and try it out */ if (bindf = fopen (fspec, "r")) { fclose (bindf); return (fspec); } } } /* always try the current directory first */ if (bindf = fopen (fname, "r")) { fclose (bindf); return (fname); } /* get the PATH variable */ path = getenv ("PATH"); if (path != NULL) while (*path) { /* build next possible file spec */ sp = fspec; while (*path && (*path != PATHCHR)) *sp++ = *path++; /* add a terminating dir separator if we need it */ if (sp[-1] != SEPCHAR) *sp++ = SEPCHAR; *sp = 0; strcat (fspec, fname); /* and try it out */ if (bindf = fopen (fspec, "r")) { fclose (bindf); return (fspec); } if (*path == PATHCHR) ++path; } return (NULL); /* no such luck */ } /* interactive method for loading binding file * (uses above routine, obviously) */ char load_extend () { #ifdef CUSTOMIZE register char s; char fname[NFILEN]; if ((s = ereply (MSG_bnd_file, fname, NFILEN, NULL)) != TRUE) return (s); check_extend (fname); writ_echo (okmsg); #endif return (TRUE); } int find_keyval (name) char *name; { SYMBOL *sp; int key; for (key = 0; key < NKEYS; ++key) { /* For all keys. */ sp = binding[key]; if (sp != NULL && (strcmp (sp->s_name, name) == 0)) return (key); } return (0); } beav-140/file.c0000644000175000001440000004517005667134707013345 0ustar samusers00000000000000/* * File commands. */ #include #include #include #include "def.h" char load_file (); char readin (); void makename (); bool writeout (); bool parse_f_name (); A32 ffseek (); A32 file_len (); extern char MSG_rd_file[]; extern char MSG_trash[]; extern char MSG_ins_file[]; extern char MSG_not_fnd[]; extern char MSG_visit[]; extern char MSG_view[]; extern char MSG_buf_ex[]; extern char MSG_old_buf[]; extern char MSG_buf_nam[]; extern char MSG_cnt_cr[]; extern char MSG_reading[]; extern char MSG_read_lx[]; extern char MSG_no_mem_rd[]; extern char MSG_wr_file[]; extern char MSG_no_fn[]; extern char MSG_bk_err[]; extern char MSG_writing[]; extern char MSG_wrot_n[]; extern char MSG_fil_nam[]; extern char MSG_null[]; extern char ERR_parse_fn[]; extern char ERR_addr_neg[]; extern char ERR_f_size[]; static int ughlyflag = FALSE; /* * Read a file into the current * buffer. This is really easy; all you do it * find the name of the file, and call the standard * "read a file into the current buffer" code. */ char fileread () { register char s; char fname[NFILEN]; A32 start, end; if ((s = ereply (MSG_rd_file, fname, NFILEN, NULL)) != TRUE) return (s); if (parse_f_name (fname, &start, &end)) { adjustcase (fname); return (readin (fname, start, end)); } return (TRUE); } /* insert file into current buffer - use readin, and yank */ char fileinsert () { register char s; char bname[NBUFN], fname[NFILEN]; A32 start, end; register char *trash = MSG_trash; strcpy (bname, curbp->b_bname); /* save current buffer */ if ((s = _usebuffer (trash)) == 0) /* temp buffer */ return (s); if ((s = ereply (MSG_ins_file, fname, NFILEN, NULL)) != TRUE) return (s); /* if file name and starting and ending addresses are good */ if (parse_f_name (fname, &start, &end)) { adjustcase (fname); if ((s = readin (fname, start, end)) == 0) { writ_echo (MSG_not_fnd); _usebuffer (bname); _killbuffer (trash); return (s); } if ((s = _usebuffer (bname)) == 0) { _killbuffer (trash); return (s); } if ((s = _yankbuffer (trash)) == 0) { _killbuffer (trash); return (s); } writ_echo (okmsg); } else { _usebuffer (bname); _killbuffer (trash); return (FALSE); } if ((s = _killbuffer (trash)) == 0) return (s); wind_on_dot (curwp); return (s); } /* * Select a file for editing. * Look around to see if you can find the * fine in another buffer; if you can find it * just switch to the buffer. If you cannot find * the file, create a new buffer, read in the * text, and switch to the new buffer. * * also various hacked versions for auto load, and * file-vist with auto window split, and readonly (view-file) (jam) */ char file_visit (f, n, k) int f, n, k; { char fname[NFILEN]; char s; A32 start, end; if ((s = ereply (MSG_visit, fname, NFILEN, NULL)) != TRUE) return (s); if (!parse_f_name (fname, &start, &end)) return (FALSE); splitwind (); return (load_file (fname, start, end)); } /* like filevisit, only read only */ char viewfile () { char fname[NFILEN]; char s; A32 start, end; if ((s = ereply (MSG_view, fname, NFILEN, NULL)) != TRUE) return (s); ughlyflag = TRUE; if (!parse_f_name (fname, &start, &end)) return (FALSE); s = load_file (fname, start, end); if (s) curbp->b_flag |= BFVIEW; ughlyflag = FALSE; return (s); } char filevisit () { char fname[NFILEN]; char s; A32 start, end; if ((s = ereply (MSG_visit, fname, NFILEN, NULL)) != TRUE) return (s); if (!parse_f_name (fname, &start, &end)) return (FALSE); return (load_file (fname, start, end)); } char load_file (fname, start, end) /* jam */ char *fname; A32 start, end; { register BUFFER *bp; register WINDOW *wp; register LINE *lp; register int i; char s; char bname[NBUFN]; extern int initial_load; /* jam */ static int append = 0; adjustcase (fname); for (bp = bheadp; bp != NULL; bp = bp->b_bufp) { if (strcmp (bp->b_fname, fname) == 0) { if (ughlyflag == TRUE) { writ_echo (MSG_buf_ex); return (FALSE); } if (--curbp->b_nwnd == 0) { curbp->b_type = BTFILE; curbp->b_dotp = curwp->w_dotp; curbp->b_doto = curwp->w_doto; curbp->b_unit_offset = curwp->w_unit_offset; curbp->b_markp = curwp->w_markp; curbp->b_marko = curwp->w_marko; } curbp = bp; curwp->w_bufp = bp; if (bp->b_nwnd++ == 0) { curwp->w_dotp = bp->b_dotp; curwp->w_doto = bp->b_doto; curwp->w_unit_offset = bp->b_unit_offset; curwp->w_markp = bp->b_markp; curwp->w_marko = bp->b_marko; } else { wp = wheadp; while (wp != NULL) { if (wp != curwp && wp->w_bufp == bp) { curwp->w_dotp = wp->w_dotp; curwp->w_doto = wp->w_doto; curwp->w_unit_offset = wp->w_unit_offset; curwp->w_markp = wp->w_markp; curwp->w_marko = wp->w_marko; break; } wp = wp->w_wndp; } } lp = curwp->w_dotp; i = curwp->w_ntrows / 2; while (i-- && lback (lp) != curbp->b_linep) lp = lback (lp); curwp->w_linep = lp; curwp->w_flag |= WFMODE | WFHARD; if (kbdmop == NULL) { writ_echo (MSG_old_buf); } return (TRUE); } } makename (bname, fname); /* New buffer name. */ while ((bp = bfind (bname, FALSE)) != NULL) { if (initial_load) /* patch old name */ { funky_name (bname, append++); bp = NULL; break; } s = ereply (MSG_buf_nam, bname, NBUFN, NULL); if (s == ABORT) /* ^G to just quit */ return (s); if (strcmp (bp->b_bname, bname) == 0 || s == FALSE) { /* CR to clobber it */ makename (bname, fname); break; } } if (bp == NULL && (bp = bfind (bname, TRUE)) == NULL) { err_echo (MSG_cnt_cr); return (FALSE); } if (--curbp->b_nwnd == 0) { /* Undisplay. */ curbp->b_type = BTFILE; curbp->b_dotp = curwp->w_dotp; curbp->b_doto = curwp->w_doto; curbp->b_unit_offset = curwp->w_unit_offset; curbp->b_markp = curwp->w_markp; curbp->b_marko = curwp->w_marko; } curbp = bp; /* Switch to it. */ curwp->w_bufp = bp; curbp->b_nwnd++; return (readin (fname, start, end)); /* Read it in. */ } /* * Read the file "fname" into the current buffer. * Make all of the text in the buffer go away, after checking * for unsaved changes. This is called by the "read" command, the * "visit" command, and the mainline (for "beav file"). If the * BACKUP conditional is set, then this routine also does the read * end of backup processing. The BFBAK flag, if set in a buffer, * says that a backup should be taken. It is set when a file is * read in, but not on a new file (you don't need to make a backup * copy of nothing). Return a standard status. Print a summary * (lines read, error message) out as well. */ char readin (fname, start, end) char fname[]; A32 start, end; { register LINE *lp1; register LINE *lp2; register WINDOW *wp; register BUFFER *bp; register char s, m; long byte_cnt; LPOS req_chars; char buf[NCOL], buf1[NCOL]; A32 temp; m = TRUE; byte_cnt = 0; bp = curbp; /* Cheap. */ if ((s = bclear (bp)) != TRUE) /* Might be old. */ return (s); #if BACKUP bp->b_flag &= ~(BFCHG | BFBAK); /* No change, backup. */ #else bp->b_flag &= ~BFCHG; /* No change. */ #endif if ((start == 0L) && (end == MAXPOS)) strcpy (bp->b_fname, fname); else strcpy (bp->b_fname, MSG_null); bp->b_file_size = 0; bp->b_type = BTFILE; if ((s = ffropen (fname)) == FIOERR || s == FIOFNF) /* jam */ goto out; bp->b_file_size = file_len (); /* get the file lenth */ sprintf (buf, MSG_reading, fname); /* jam */ writ_echo (buf); temp = ffseek (start); if (temp != start) { sprintf (buf1, ERR_f_size, R_POS_FMT (curwp)); sprintf (buf, buf1, temp); writ_echo (buf); return (FALSE); } /* only read the requested number of characters */ if ((end - start) > NLINE) req_chars = NLINE; else req_chars = (int) (end - start); if ((lp1 = lalloc (req_chars)) == NULL) { bp->b_flag |= BFVIEW; /* if no memory set to read only mode */ m = FALSE; /* flag memory allocation error */ } else { while ((s = ffgetline (lp1->l_text, lp1->l_size, &lp1->l_used)) == FIOSUC) { /* this code breaks rules for knowing how lines * are stored and linked together, oh well */ lp2 = lback (curbp->b_linep); lp2->l_fp = lp1; lp1->l_fp = curbp->b_linep; lp1->l_bp = lp2; curbp->b_linep->l_bp = lp1; lp1->l_file_offset = byte_cnt; /* file offset from begining */ byte_cnt += (long) lp1->l_used; /* number of bytes read in */ start += (long) lp1->l_used; if (end <= start) break; /* stop reading after the requested number of characters */ if (end < start + req_chars) { req_chars = end - start; } if ((lp1 = lalloc (req_chars)) == NULL) { bp->b_flag |= BFVIEW; /* if no memory set to read only mode */ m = FALSE; /* flag memory allocation error */ break; } if ((byte_cnt & 0x7fff) == 0) { sprintf (buf1, MSG_read_lx, R_POS_FMT (curwp)); sprintf (buf, buf1, (ulong) byte_cnt); writ_echo (buf); /* check if we should quit */ if (ttkeyready ()) { wind_on_dot_all (); if (ttgetc () == CTL_G) /* was it an abort key? */ { s = FIOERR; break; } } } } } ffclose (); /* Ignore errors. */ if (s == FIOEOF && kbdmop == NULL) { /* Don't zap an error. */ sprintf (buf1, MSG_read_lx, R_POS_FMT (curwp)); sprintf (buf, buf1, byte_cnt); writ_echo (buf); } if (m == FALSE && kbdmop == NULL) { /* Don't zap an error. */ sprintf (buf, MSG_no_mem_rd); err_echo (buf); } #if BACKUP curbp->b_flag |= BFBAK; /* Need a backup. */ #endif out: for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { if (wp->w_bufp == curbp) { wp->w_linep = lforw (curbp->b_linep); wp->w_dotp = lforw (curbp->b_linep); wp->w_doto = 0; wp->w_unit_offset = 0; wp->w_markp = NULL; wp->w_marko = 0; wp->w_flag |= WFMODE | WFHARD; } } /* so tell yank-buffer about it */ if ((blistp->b_nwnd != 0) &&/* update buffer display */ (blistp->b_type == BTLIST)) listbuffers (); if (s == FIOERR || s == FIOFNF) /* False if error. */ return (FALSE); return (TRUE); } /* * Take a file name, and from it * fabricate a buffer name. This routine knows * about the syntax of file names on the target system. * BDC1 left scan delimiter. * BDC2 optional second left scan delimiter. * BDC3 optional right scan delimiter. */ void makename (bname, fname) char bname[]; char fname[]; { register char *cp1; register char *cp2; cp1 = &fname[0]; while (*cp1 != 0) ++cp1; #ifdef BDC2 while (cp1 != &fname[0] && cp1[-1] != BDC1 && cp1[-1] != BDC2) --cp1; #else while (cp1 != &fname[0] && cp1[-1] != BDC1) --cp1; #endif cp2 = &bname[0]; #ifdef BDC3 while (cp2 != &bname[NBUFN - 1] && *cp1 != 0 && *cp1 != BDC3) *cp2++ = *cp1++; #else while (cp2 != &bname[NBUFN - 1] && *cp1 != 0) *cp2++ = *cp1++; #endif *cp2 = 0; } /* * Ask for a file name, and write the * contents of the current buffer to that file. * Update the remembered file name and clear the * buffer changed flag. This handling of file names * is different from the earlier versions, and * is more compatable with Gosling EMACS than * with ITS EMACS. */ char filewrite () { register WINDOW *wp; register char s; char fname[NFILEN]; A32 start, end; if ((s = ereply (MSG_wr_file, fname, NFILEN, NULL)) != TRUE) return (s); if (!parse_f_name (fname, &start, &end)) return (FALSE); adjustcase (fname); if ((s = writeout (fname, start, end, S_IREAD | S_IWRITE)) == TRUE) { strcpy (curbp->b_fname, fname); curbp->b_flag &= ~BFCHG; wp = wheadp; /* Update mode lines. */ while (wp != NULL) { if (wp->w_bufp == curbp) wp->w_flag |= WFMODE; wp = wp->w_wndp; } } #if BACKUP curbp->b_flag &= ~BFBAK; /* No backup. */ #endif return (s); } /* * Save the contents of the current buffer back into * its associated file. Do nothing if there have been no changes * (is this a bug, or a feature). Error if there is no remembered * file name. If this is the first write since the read or visit, * then a backup copy of the file is made. */ char filesave () { register WINDOW *wp; register char s; struct stat st; if ((curbp->b_flag & BFCHG) == 0) /* Return, no changes. */ return (TRUE); if (curbp->b_fname[0] == 0) /* Must have a name. */ { if (!(curbp->b_type == BTSAVE)) /* yanked buffer */ { writ_echo (MSG_no_fn); } return (FALSE); } st.st_mode = S_IREAD | S_IWRITE; /* set default */ #if BACKUP if ((curbp->b_flag & BFBAK) != 0) { /* get the mode of the file */ stat (curbp->b_fname, &st); s = fbackupfile (curbp->b_fname); if (s == ABORT) /* Hard error. */ return (s); if (s == FALSE /* Softer error. */ && (s = eyesno (MSG_bk_err)) != TRUE) return (s); } #endif if ((s = writeout (curbp->b_fname, 0L, MAXPOS, st.st_mode)) == TRUE) { curbp->b_flag &= ~BFCHG;/* No change. */ curbp->b_flag &= ~BFBAD;/* if it was trashed, forget it now */ wp = wheadp; /* Update mode lines. */ while (wp != NULL) { if (wp->w_bufp == curbp) wp->w_flag |= WFMODE; wp = wp->w_wndp; } } #if BACKUP curbp->b_flag &= ~BFBAK; /* No backup. */ #endif return (s); } /* * This function performs the details of file * writing. Uses the file management routines in the * "fileio.c" package. The number of lines written is * displayed. Sadly, it looks inside a LINE; provide * a macro for this. Most of the grief is error * checking of some sort. * The file permissions are set as requested. */ bool writeout (fn, start, end, mode) char *fn; A32 start, end; ushort mode; { register int s, num_chars; register LINE *lp; register long nbytes; char buf[NCOL], buf1[NCOL]; A32 temp; if ((s = ffwopen (fn, mode)) != FIOSUC) /* Open writes message. */ return (FALSE); temp = ffseek (start); if (temp != start) { sprintf (buf1, ERR_f_size, R_POS_FMT (curwp)); sprintf (buf, buf1, temp); writ_echo (buf); return (FALSE); } sprintf (buf, MSG_writing, fn); /* jam */ writ_echo (buf); /* insure that the help screen reflects the latest bindings */ if (curbp == blistp) wallchart (0, 0, 0); lp = lforw (curbp->b_linep);/* First line. */ nbytes = 0; /* Number of bytes. */ temp = end - start; /* number of bytes to write */ while (lp != curbp->b_linep) { if (curbp == blistp) { /* special list buffer */ num_chars = HENDCOL;/* limit line length */ lp->l_text[num_chars - 1] = '\n'; } else { /* standard buffer */ if (nbytes + (long) llength (lp) > temp) num_chars = (int) (temp - nbytes); else num_chars = llength (lp); } if ((s = ffputline (&lp->l_text[0], num_chars)) != FIOSUC) break; nbytes += num_chars; if (temp <= nbytes) break; lp = lforw (lp); if ((nbytes & 0x7fff) == 0) { sprintf (buf1, MSG_wrot_n, R_POS_FMT (curwp)); sprintf (buf, buf1, (ulong) nbytes); writ_echo (buf); /* check if we should quit */ if (ttkeyready ()) { wind_on_dot_all (); if (ttgetc () == CTL_G) /* was it an abort key? */ { s = FIOERR; break; } } } } if (s == FIOSUC) { /* No write error. */ s = ffclose (); if (s == FIOSUC && kbdmop == NULL) { sprintf (buf1, MSG_wrot_n, R_POS_FMT (curwp)); sprintf (buf, buf1, (long) nbytes); writ_echo (buf); } } else /* Ignore close error */ ffclose (); /* if a write error. */ curbp->b_file_size = nbytes;/* update file size */ if ((blistp->b_nwnd != 0) &&/* update buffer display */ (blistp->b_type == BTLIST)) listbuffers (); if (s != FIOSUC) /* Some sort of error. */ return (FALSE); return (TRUE); } /* * The command allows the user * to modify the file name associated with * the current buffer. It is like the "f" command * in UNIX "ed". The operation is simple; just zap * the name in the BUFFER structure, and mark the windows * as needing an update. You can type a blank line at the * prompt if you wish. */ char filename () { register WINDOW *wp; register char s; char fname[NFILEN]; A32 start, end; if ((s = ereply (MSG_fil_nam, fname, NFILEN, NULL)) == ABORT) return (s); if (!parse_f_name (fname, &start, &end)) return (FALSE); adjustcase (fname); curbp->b_flag |= BFCHG; /* jam - on name change, set modify */ BUF_START (curwp) = start; l_fix_up (curbp->b_linep->l_fp); /* adjust file offsets from first line */ strcpy (curbp->b_fname, fname); /* Fix name. */ wp = wheadp; /* Update mode lines. */ while (wp != NULL) { if (wp->w_bufp == curbp) wp->w_flag |= WFMODE; wp = wp->w_wndp; } #if BACKUP curbp->b_flag &= ~BFBAK; /* No backup. */ #endif return (TRUE); } /* * Get the length parameters that were entered with the file name. * There can be the file name only. * There can be a file name and a starting position. * There can be a name a starting position and an ending position. * There can be a name a starting position and a length. * * input: * fn pointer to file name string to parse. * * output: * fn pointer to null terminated file name. * start pointer to the starting point in file (default = 0) * end pointer to the end point in file (default = -1) * return FALSE if file name or addresses are bad. */ bool parse_f_name (fn, start, end) char *fn; A32 *start, *end; { char buf[NFILEN], buf1[NCOL], fmt[NCOL]; int i_cnt; /* build up format string according to the current screen format */ sprintf (fmt, "%s %s %s", "%s", R_POS_FMT (curwp), R_POS_FMT (curwp)); *start = 0L; *end = MAXPOS; sscanf (fn, fmt, buf, start, end); if (*end != MAXPOS) { for (i_cnt = strlen (fn) - 1; i_cnt >= 0; i_cnt--) { if (fn[i_cnt] == '+') { *end += *start; break; } } } /* start should preceed end */ if (*start > *end) { sprintf (buf1, ERR_parse_fn, R_POS_FMT (curwp), R_POS_FMT (curwp)); sprintf (buf, buf1, *start, *end); writ_echo (buf); return (FALSE); } /* error if addresses are negative */ if ((*start < 0) || (*end < 0)) { writ_echo (ERR_addr_neg); return (FALSE); } /* deposit null terminated file name */ strcpy (fn, buf); return (TRUE); } beav-140/fileio.c0000644000175000001440000001357005667134707013674 0ustar samusers00000000000000/* * file I/O. */ #ifdef UNIX #include #include #include #endif #ifdef AMIGA #include #include #include #endif #include "def.h" extern char MSG_cnt_wr[]; extern char MSG_cnt_rd[]; extern char MSG_wr_io_er[]; extern char MSG_rd_er[]; extern char MSG_bak[]; extern char MSG_backup[]; extern char MSG_back_er[]; extern char MSG_back_of[]; #ifdef MSDOS static FILE *ffp; #endif #ifdef UNIX static int ffp; #endif #ifdef AMIGA static int ffp; #endif /* * Open a file for reading. */ char ffropen (fn) char *fn; { #ifdef MSDOS if ((ffp = fopen (fn, "rb")) == NULL) /* pvr */ #endif #ifdef OS2 if ((ffp = open (fn, O_RDONLY | O_BINARY)) == -1) /* pvr */ #else #ifdef UNIX if ((ffp = open (fn, O_RDONLY)) == -1) /* pvr */ #endif #endif #ifdef AMIGA if ((ffp = open (fn, O_RDONLY)) == -1) /* pvr */ #endif return (FIOERR); return (FIOSUC); } /* * Get the file length */ #ifdef AMIGA A32 file_len (char *fname) { struct stat st; if (stat (fname, &st) == -1) return (-1); return (st.st_size); } #else /* AMIGA */ A32 file_len () { #ifdef MSDOS return (filelength (fileno (ffp))); #endif #ifdef UNIX struct stat st; if (fstat (ffp, &st) == -1) return (-1); return (st.st_size); #endif } #endif /* AMIGA */ /* * Open a file for writing. * Set file permissions as requested * Return TRUE if all is well, and * FALSE on error (cannot create). */ bool ffwopen (fn, mode) char *fn; int mode; { #ifdef MSDOS if ((ffp = fopen (fn, "wb")) == NULL) /* pvr */ #endif #ifdef OS2 mode &= (S_IREAD | S_IWRITE); mode |= S_IREAD; if ((ffp = open (fn, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode)) == -1) #else #ifdef UNIX /* set perms as in original file 1.31 */ if ((ffp = open (fn, O_WRONLY | O_CREAT, mode)) == -1) #endif #endif #ifdef AMIGA /* set perms as in original file 1.31 */ if ((ffp = open (fn, O_WRONLY | O_CREAT, mode)) == -1) /* pvr */ #endif { err_echo (MSG_cnt_wr); return (FIOERR); } return (FIOSUC); } /* * Close a file. * Should look at the status. */ char ffclose () { #ifdef MSDOS fclose (ffp); #endif #ifdef UNIX close (ffp); #endif #ifdef AMIGA close (ffp); #endif return (FIOSUC); } /* * Write a line to the already * opened file. The "buf" points to the * buffer, and the "nbuf" is its length. pvr * Return the status. */ char ffputline (buf, nbuf) register char buf[]; int nbuf; { register int i; #ifdef MSDOS i = fwrite (buf, 1, nbuf, ffp); #endif #ifdef UNIX i = write (ffp, buf, nbuf); #endif #ifdef AMIGA i = write (ffp, buf, nbuf); #endif if ((i != nbuf) #ifdef MSDOS || (ferror (ffp) != FALSE)) #else ) #endif { err_echo (MSG_wr_io_er); return (FIOERR); } return (FIOSUC); } /* * Read a line from a file, and store the bytes * in the supplied buffer. Stop on end of file or after 'nbuf' characters. pvr * the first byte in the buffer is the length in bytes. */ char ffgetline (buf, nbuf, rbuf) register char *buf; register LPOS *rbuf, nbuf; { #ifdef MSDOS *rbuf = fread (buf, 1, nbuf, ffp); #endif #ifdef UNIX *rbuf = read (ffp, buf, nbuf); #endif #ifdef AMIGA *rbuf = read (ffp, buf, nbuf); #endif /* End of file. */ #ifdef MSDOS if (ferror (ffp) != FALSE) { err_echo (MSG_rd_er); return (FIOERR); } #endif if (*rbuf == 0) return (FIOEOF); return (FIOSUC); } /* * Seek to specified position in file. * Return the actual position in the file. */ A32 ffseek (posn) A32 posn; { #ifdef MSDOS fseek (ffp, posn, SEEK_SET); return (ftell (ffp)); #endif #ifdef UNIX return (lseek (ffp, posn, 0)); #endif #ifdef AMIGA return (lseek (ffp, posn, 0)); #endif } /* * Some backup user on MS-DOS might want * to determine some rule for doing backups on that * system, and fix this. I don't use MS-DOS, so I don't * know what the right rules would be. Return TRUE so * the caller does not abort a write. * Under UNIX just append the .bak postfix. */ #ifdef BACKUP bool fbackupfile (fname) char *fname; { char backname[NFILEN]; char *source, *backup; char buf[NCOL]; source = fname; backup = backname; while ((*source > 0) #if defined(MSDOS) || defined(OS2) && (*source != '.')) #else ) #endif { *backup = *source; backup++; source++; *backup = 0; } #ifdef OS2 strcpy (backup, source); strcat (backup, "~"); if (!isvalid (backname)) strcpy (backup, ".bak"); #else strcat (backname, MSG_bak); #endif sprintf (buf, MSG_backup, fname, backname); writ_echo (buf); unlink (backname); #ifdef NORENAME if ((link (fname, backname) != 0) || (unlink (fname) != 0)) #else if (rename (fname, backname) > 0) #endif { sprintf (buf, MSG_back_er, fname, backname); err_echo (buf); return (FALSE); } return (TRUE); /* Hack. */ } #endif /* * The string "fn" is a file name. * Perform any required case adjustments. All systems * we deal with so far have case insensitive file systems. * We zap everything to lower case. The problem we are trying * to solve is getting 2 buffers holding the same file if * you visit one of them with the "caps lock" key down. * On UNIX and AMIGA file names are dual case, so we leave * everything alone. */ void adjustcase (fn) register char *fn; { register int c; while ((c = *fn) != 0) { if (c >= 'A' && c <= 'Z') *fn = c + 'a' - 'A'; ++fn; } } #ifdef OS2 #define INCL_NOPM #define INCL_ERRORS #include int isvalid (char *name) { HFILE hf; #ifdef __32BIT__ ULONG uAction; #else USHORT uAction; #endif switch (DosOpen (name, &hf, &uAction, 0, 0, FILE_OPEN, OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0)) { case ERROR_INVALID_NAME: case ERROR_FILENAME_EXCED_RANGE: return FALSE; case NO_ERROR: DosClose (hf); default: return TRUE; } } #endif beav-140/format.c0000644000175000001440000002223305667134707013711 0ustar samusers00000000000000/* * The module devines the format of the screen display. */ #include "def.h" extern char hex_str[]; extern char hex_l_str[]; extern char octal_str[]; extern char octal_l_str[]; extern char decimal_str[]; extern char decimal_l_str[]; #if FLOAT_DISP extern char float_str[]; #endif extern char char_str[]; /* These structures contain the format for the displayed line */ #define FC 13 #define FS 0 uchar ascii_s_posn[] = { FS + 0, FS + 1, FS + 2, FS + 3, FS + 4, FS + 5, FS + 6, FS + 7, FS + 8, FS + 9, FS + 10, FS + 11, FS + 12, FS + 13, FS + 14, FS + 15, FS + 16, FS + 17, FS + 18, FS + 19, FS + 20, FS + 21, FS + 22, FS + 23, FS + 24, FS + 25, FS + 26, FS + 27, FS + 28, FS + 29, FS + 30, FS + 31, FS + 32, FS + 33, FS + 34, FS + 35, FS + 36, FS + 37, FS + 38, FS + 39, FS + 40, FS + 41, FS + 42, FS + 43, FS + 44, FS + 45, FS + 46, FS + 47, FS + 48, FS + 49, FS + 50, FS + 51, FS + 52, FS + 53, FS + 54, FS + 55, FS + 56, FS + 57, FS + 58, FS + 59, FS + 60, FS + 61, FS + 62, FS + 63, FS + 64, FS + 65, FS + 66, FS + 67, FS + 68, FS + 69, FS + 70, FS + 71, FS + 72, FS + 73, FS + 74, FS + 75, FS + 76, FS + 77, FS + 78, FS + 79, }; ROW_FMT text_fmt = { TEXT, BYTES, 128, 128, 128, 1, 1, FALSE, char_str, hex_l_str, hex_str, ascii_s_posn, 0}; ROW_FMT ascii_fmt = { ASCII, BYTES, 64, 64, 64, 1, 1, FALSE, char_str, hex_l_str, hex_str, &ascii_s_posn[FC], 0}; ROW_FMT ascii_s_fmt = { ASCII, BYTES, 32, 32, 1, 1, 1, FALSE, char_str, hex_l_str, hex_str, ascii_s_posn, 0}; ROW_FMT ebcdic_fmt = { EBCDIC, BYTES, 64, 64, 64, 1, 1, FALSE, char_str, hex_l_str, hex_str, &ascii_s_posn[FC], 0}; ROW_FMT ebcdic_s_fmt = { EBCDIC, BYTES, 32, 32, 1, 1, 1, FALSE, char_str, hex_l_str, hex_str, ascii_s_posn, 0}; uchar octal_8_posn[] = { FC, FC + 4, FC + 8, FC + 12, FC + 16, FC + 20, FC + 24, FC + 28, FC + 33, FC + 37, FC + 41, FC + 45, FC + 49, FC + 53, FC + 57, FC + 61 }; ROW_FMT octal_8_fmt = { OCTAL, BYTES, 16, 16, 16, 1, 3, TRUE, octal_str, octal_l_str, octal_str, octal_8_posn, 0}; uchar octal_s_8_posn[] = { FS, FS + 4, FS + 8, FS + 12, FS + 16, FS + 20, FS + 24, FS + 28, FS + 32, FS + 36, FS + 40, FS + 44, FS + 48, FS + 52, FS + 56, FS + 60, FS + 64, FS + 68, FS + 72, FS + 76, FS + 80 }; ROW_FMT octal_s_8_fmt = { OCTAL, BYTES, 8, 8, 1, 1, 3, TRUE, octal_str, octal_l_str, octal_str, octal_s_8_posn, 0}; uchar octal_16_posn[] = { FC, FC + 7, FC + 14, FC + 21, FC + 29, FC + 36, FC + 43, FC + 50 }; ROW_FMT octal_16_fmt = { OCTAL, WORDS, 8, 16, 16, 2, 6, TRUE, octal_str, octal_l_str, octal_str, octal_16_posn, 0}; uchar octal_s_16_posn[] = { FS, FS + 7, FS + 14, FS + 21, FS + 28, FS + 35, FS + 42, FS + 49, FS + 56, FS + 63, FS + 70, FS + 77 }; ROW_FMT octal_s_16_fmt = { OCTAL, WORDS, 4, 8, 2, 2, 6, TRUE, octal_str, octal_l_str, octal_str, octal_s_16_posn, 0}; uchar octal_32_posn[] = { FC, FC + 12, FC + 25, FC + 37 }; ROW_FMT octal_32_fmt = { OCTAL, DWORDS, 4, 16, 16, 4, 11, TRUE, octal_l_str, octal_l_str, octal_str, octal_32_posn, 0}; uchar octal_s_32_posn[] = { FS, FS + 12, FS + 24, FS + 36, FS + 48, FS + 60, FS + 72 }; ROW_FMT octal_s_32_fmt = { OCTAL, DWORDS, 2, 8, 4, 4, 11, TRUE, octal_l_str, octal_l_str, octal_str, octal_s_32_posn,}; ROW_FMT decimal_8_fmt = { DECIMAL, BYTES, 16, 16, 16, 1, 3, TRUE, decimal_str, decimal_l_str, decimal_str, octal_8_posn, 0}; ROW_FMT decimal_s_8_fmt = { DECIMAL, BYTES, 8, 8, 1, 1, 3, TRUE, decimal_str, decimal_l_str, decimal_str, octal_s_8_posn, 0}; uchar decimal_16_posn[] = { FC, FC + 6, FC + 12, FC + 18, FC + 25, FC + 31, FC + 37, FC + 43 }; ROW_FMT decimal_16_fmt = { DECIMAL, WORDS, 8, 16, 16, 2, 5, TRUE, decimal_str, decimal_l_str, decimal_str, decimal_16_posn, 0}; uchar decimal_s_16_posn[] = { FS, FS + 6, FS + 12, FS + 18, FS + 24, FS + 30, FS + 36, FS + 42, FS + 48, FS + 54, FS + 60, FS + 66, FS + 72, FS + 78 }; ROW_FMT decimal_s_16_fmt = { DECIMAL, WORDS, 4, 8, 2, 2, 5, TRUE, decimal_str, decimal_l_str, decimal_str, decimal_s_16_posn, 0}; uchar decimal_32_posn[] = { FC, FC + 11, FC + 23, FC + 34 }; ROW_FMT decimal_32_fmt = { DECIMAL, DWORDS, 4, 16, 16, 4, 10, TRUE, decimal_l_str, decimal_l_str, decimal_str, decimal_32_posn, 0}; uchar decimal_s_32_posn[] = { FS, FS + 11, FS + 22, FS + 33, FS + 44, FS + 55, FS + 66, FS + 77 }; ROW_FMT decimal_s_32_fmt = { DECIMAL, DWORDS, 4, 16, 4, 4, 10, TRUE, decimal_l_str, decimal_l_str, decimal_str, decimal_s_32_posn, 0}; #if FLOAT_DISP uchar float_64_posn[] = { FC, FC + 32 }; ROW_FMT float_64_fmt = { FLOAT, DOUBLES, 2, 16, 16, 8, 24, TRUE, float_str, decimal_l_str, decimal_str, float_64_posn, 0}; uchar float_s_64_posn[] = { FS, FS + 30 }; ROW_FMT float_s_64_fmt = { FLOAT, DOUBLES, 2, 16, 4, 8, 22, TRUE, float_str, decimal_l_str, decimal_str, float_s_64_posn, 0}; #endif uchar hex_8_posn[] = { FC, FC + 3, FC + 6, FC + 9, FC + 12, FC + 15, FC + 18, FC + 21, FC + 25, FC + 28, FC + 31, FC + 34, FC + 37, FC + 40, FC + 43, FC + 46, FC + 50, FC + 51, FC + 52, FC + 53, FC + 54, FC + 55, FC + 56, FC + 57, FC + 58, FC + 59, FC + 60, FC + 61, FC + 62, FC + 63, FC + 64, FC + 65 }; ROW_FMT hex_8_fmt = { HEX, BYTES, 16, 16, 16, 1, 2, TRUE, hex_str, hex_l_str, hex_str, hex_8_posn, 0}; uchar hex_s_8_posn[] = { FS, FS + 3, FS + 6, FS + 9, FS + 12, FS + 15, FS + 18, FS + 21, FS + 24, FS + 27, FS + 30, FS + 33, FS + 36, FS + 39, FS + 42, FS + 45, FS + 48, FS + 51, FS + 54, FS + 57, FS + 60, FS + 63, FS + 66, FS + 69, FS + 72, FS + 75, FS + 78, FS + 80, FS + 80, FS + 80, FS + 80, FS + 80 }; ROW_FMT hex_s_8_fmt = { HEX, BYTES, 8, 8, 1, 1, 2, TRUE, hex_str, hex_l_str, hex_str, hex_s_8_posn, 0}; uchar hex_16_posn[] = { FC, FC + 5, FC + 10, FC + 15, FC + 21, FC + 26, FC + 31, FC + 36 }; ROW_FMT hex_16_fmt = { HEX, WORDS, 8, 16, 16, 2, 4, TRUE, hex_str, hex_l_str, hex_str, hex_16_posn, 0}; uchar hex_s_16_posn[] = { FS, FS + 5, FS + 10, FS + 15, FS + 20, FS + 25, FS + 30, FS + 35, FS + 40, FS + 45, FS + 50, FS + 55, FS + 60, FS + 65, FS + 70, FS + 75 }; ROW_FMT hex_s_16_fmt = { HEX, WORDS, 8, 16, 2, 2, 4, TRUE, hex_str, hex_l_str, hex_str, hex_s_16_posn, 0}; uchar hex_32_posn[] = { FC, FC + 9, FC + 19, FC + 28 }; ROW_FMT hex_32_fmt = { HEX, DWORDS, 4, 16, 16, 4, 8, TRUE, hex_l_str, hex_l_str, hex_str, hex_32_posn, 0}; uchar hex_s_32_posn[] = { FS, FS + 9, FS + 18, FS + 27, FS + 36, FS + 45, FS + 54, FS + 63, FS + 72 }; ROW_FMT hex_s_32_fmt = { HEX, DWORDS, 4, 16, 4, 4, 8, TRUE, hex_l_str, hex_l_str, hex_str, hex_s_32_posn, 0}; ROW_FMT binary_8_fmt = { BINARY, BYTES, 4, 4, 4, 1, 8, FALSE, hex_str, hex_l_str, hex_str, hex_32_posn, 0}; /* use the hex position array */ ROW_FMT binary_s_8_fmt = { BINARY, BYTES, 4, 4, 1, 1, 8, FALSE, hex_str, hex_l_str, hex_str, hex_s_32_posn, 0}; /* use the hex position array */ uchar binary_16_posn[] = { FC, FC + 17, FC + 34, FC + 51 }; ROW_FMT binary_16_fmt = { BINARY, WORDS, 4, 8, 8, 2, 16, FALSE, hex_str, hex_l_str, hex_str, binary_16_posn, 0}; uchar binary_s_16_posn[] = { FS, FS + 17, FS + 34, FS + 51, FS + 68 }; ROW_FMT binary_s_16_fmt = { BINARY, WORDS, 2, 4, 2, 2, 16, FALSE, hex_str, hex_l_str, hex_str, binary_s_16_posn, 0}; uchar binary_32_posn[] = { FC, FC + 33 }; ROW_FMT binary_32_fmt = { BINARY, DWORDS, 2, 8, 8, 4, 32, FALSE, hex_l_str, hex_l_str, hex_str, binary_32_posn, 0}; uchar binary_s_32_posn[] = { FS, FS + 33 }; ROW_FMT binary_s_32_fmt = { BINARY, DWORDS, 1, 4, 4, 4, 32, FALSE, hex_l_str, hex_l_str, hex_str, binary_s_32_posn, 0}; /* I must do this because C does not allow forward initialization of structures */ void init_fmt () { text_fmt.r_srch_fmt = &text_fmt; ascii_fmt.r_srch_fmt = &ascii_s_fmt; ascii_s_fmt.r_srch_fmt = &ascii_fmt; ebcdic_fmt.r_srch_fmt = &ebcdic_s_fmt; ebcdic_s_fmt.r_srch_fmt = &ebcdic_fmt; octal_8_fmt.r_srch_fmt = &octal_s_8_fmt; octal_s_8_fmt.r_srch_fmt = &octal_8_fmt; octal_16_fmt.r_srch_fmt = &octal_s_16_fmt; octal_s_16_fmt.r_srch_fmt = &octal_16_fmt; octal_32_fmt.r_srch_fmt = &octal_s_32_fmt; octal_s_32_fmt.r_srch_fmt = &octal_32_fmt; decimal_8_fmt.r_srch_fmt = &decimal_s_8_fmt; decimal_s_8_fmt.r_srch_fmt = &decimal_8_fmt; decimal_16_fmt.r_srch_fmt = &decimal_s_16_fmt; decimal_s_16_fmt.r_srch_fmt = &decimal_16_fmt; decimal_32_fmt.r_srch_fmt = &decimal_s_32_fmt; decimal_s_32_fmt.r_srch_fmt = &decimal_32_fmt; #if FLOAT_DISP float_64_fmt.r_srch_fmt = &float_s_64_fmt; float_s_64_fmt.r_srch_fmt = &float_64_fmt; #endif hex_8_fmt.r_srch_fmt = &hex_s_8_fmt; hex_s_8_fmt.r_srch_fmt = &hex_8_fmt; hex_16_fmt.r_srch_fmt = &hex_s_16_fmt; hex_s_16_fmt.r_srch_fmt = &hex_16_fmt; hex_32_fmt.r_srch_fmt = &hex_s_32_fmt; hex_s_32_fmt.r_srch_fmt = &hex_32_fmt; binary_8_fmt.r_srch_fmt = &binary_s_8_fmt; binary_s_8_fmt.r_srch_fmt = &binary_8_fmt; binary_16_fmt.r_srch_fmt = &binary_s_16_fmt; binary_s_16_fmt.r_srch_fmt = &binary_16_fmt; binary_32_fmt.r_srch_fmt = &binary_s_32_fmt; binary_s_32_fmt.r_srch_fmt = &binary_32_fmt; } beav-140/kbd.c0000644000175000001440000000737105667134707013167 0ustar samusers00000000000000/* KBD.C * Terminal independent keyboard handling. */ #include "def.h" char *keystrings (); extern char MSG_tab[]; extern char MSG_esc[]; extern char MSG_ctl_x[]; extern char MSG_ctl[]; extern char MSG_fn[]; extern char MSG_ret[]; extern char MSG_bksp[]; extern char MSG_space[]; extern char MSG_rubout[]; /* * Read in a key, doing the terminal * independent prefix handling. The terminal specific * "getkbd" routine gets the first swing, and may return * one of the special codes used by the special keys * on the keyboard. The "getkbd" routine returns the * C0 controls as received; this routine moves them to * the right spot in 11 bit code. */ int getkey () { register int c; c = getkbd (); if (c == METACH) /* M- */ { c = KMETA | getctl (); #ifdef VT100KEY if ((c & KCHAR) == '[') c = KMETA | KCTRL | KCTLX | getctl (); /* flag VT100 sequence */ #endif } else if (c == CTRLCH) /* C- */ c = KCTRL | getctl (); else if (c == CTMECH) /* C-M- */ c = KCTRL | KMETA | getctl (); else if (c >= 0x00 && c <= 0x1F) /* Relocate control. */ c = KCTRL | (c + '@'); if (c == (KCTRL | 'X')) /* C-X */ c = KCTLX | getctl (); return (c); } /* * Used above. */ int getctl () { register int c; #if 1 c = getkbd (); if (c == METACH) /* M- */ c = KMETA | getctl (); else if (c == CTRLCH) /* C- */ c = KCTRL | getctl (); else if (c == CTMECH) /* C-M- */ c = KCTRL | KMETA | getctl (); else if (c >= 0x00 && c <= 0x1F) /* Relocate control. */ c = KCTRL | (c + '@'); #else c = getkey (); /* Note recursion */ if (ISLOWER (c & 0xFF)) c = (c & ~0xFF) | TOUPPER (c & 0xFF); if (c >= 0x00 && c <= 0x1F) /* Relocate control. */ c = KCTRL | (c + '@'); #endif if (ISLOWER (c & 0xFF)) c = (c & ~0xFF) | TOUPPER (c & 0xFF); return (c); } /* * Transform a key code into a name, * using a table for the special keys and combination * of some hard code and some general processing for * the rest. None of this code is terminal specific any * more. This makes adding keys easier. */ void keyname (cp, k) register char *cp; register int k; { register char *np; char nbuf[3]; static char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; *cp = 0; /* terminate previous string */ #ifdef VT100KEY if ((k & (KMETA | KCTRL | KCTLX)) == (int) (KMETA | KCTRL | KCTLX)) { sprintf (&cp[strlen (cp)], MSG_fn); sprintf (&cp[strlen (cp)], "%c", k & KCHAR); return; } #endif if (k & KFIRST) { if ((np = keystrings (k)) != NULL) { if ((k & KMETA) != 0) sprintf (&cp[strlen (cp)], MSG_esc); strcat (cp, np); } else cp[strlen (cp)] = 0;/* null string */ return; } if ((k & KCTLX) != 0) { /* Ctl-X prefix. */ sprintf (&cp[strlen (cp)], MSG_ctl_x); k &= ~KCTLX; } if ((k & KMETA) != 0) { /* Add Esc- mark. */ sprintf (&cp[strlen (cp)], MSG_esc); k &= ~KMETA; } if (k == (KCTRL | 'I')) /* Some specials. */ np = MSG_tab; else { if (k == (KCTRL | 'M')) np = MSG_ret; else if (k == (KCTRL | 'H')) np = MSG_bksp; else if (k == ' ') np = MSG_space; else if (k == 0x7F) np = MSG_rubout; else { if ((k & KCTRL) != 0) { /* Add Ctl- mark. */ sprintf (&cp[strlen (cp)], MSG_ctl); } np = &nbuf[0]; if (((k & KCHAR) >= 0x20 && (k & KCHAR) <= 0x7E) || ((k & KCHAR) >= 0xA0 && (k & KCHAR) <= 0xFE)) { nbuf[0] = k & KCHAR; /* Graphic. */ nbuf[1] = 0; } else { /* Non graphic. */ nbuf[0] = hex[(k >> 4) & 0x0F]; nbuf[1] = hex[k & 0x0F]; nbuf[2] = 0; } } } strcat (cp, np); } beav-140/language.c0000644000175000001440000003052505667134707014207 0ustar samusers00000000000000/* * This file contains all English language text srtings */ #include "def.h" /* in basic.c */ char MSG_mark_set[] = "Mark set"; char MSG_no_mark[] = "No mark in this window"; char MSG_go_b_n[] = "Goto byte number: "; char MSG_bad_num[] = "ERROR: Bad number"; /* in buffer.c */ char MSG_use_b[] = "Enter name of buffer to goto: "; char MSG_kill_b[] = "Enter name of buffer to delete: "; char MSG_no_del_m[] = "ERROR: Can't delete 'main'"; char MSG_buf_disp[] = "ERROR: Buffer is displayed - continue"; char MSG_main[] = "main"; char MSG_l_buf_h[] = "S T Size Buffer File"; char MSG_l_buf_h1[] = "- - ------ ------ ----"; char MSG_no_chg[] = "Discard changes"; char MSG_yank_b[] = "Yank from buffer: "; char MSG_no_buf[] = "ERROR: no such buffer"; char MSG_no_s_yank[] = "ERROR: can't yank to self!"; char MSG_buf_nam[] = "Buffer name: "; char MSG_bad_l[] = "ERROR: Bad line!"; char MSG_pick[] = "%s: G(oto) or K(ill) S(ave) "; char MSG_siz_chg[] = "Current buffer size may be changed"; char MSG_no_siz_chg[] = "Current buffer size is locked"; char MSG_cnt_al_b[] = "ERROR: Cannot allocate BUFFER block"; char MSG_ins_cnt[] = "Insert %s bytes, Hit Ctl-G to quit."; /* in display.c */ char MSG_prn_to[] = "Print to: "; char MSG_prog_name[] = "BEAV"; char MSG_disp_b_lst[] = " Buffer List "; char MSG_file[] = "File: "; char MSG_RO[] = " [RO]"; char MSG_WL[] = " [WL]"; char MSG_RW[] = " [RW]"; char MSG_AU[] = "[AU]"; char MSG_NOT_AU[] = " "; char MSG_curs_asc[] = "CURSOR=%08lX, ASCII"; char MSG_curs_ebc[] = "CURSOR=%08lX, EBCDIC"; char MSG_curs_hex[] = "CURSOR=%08lX,%2X HEX"; char MSG_curs_bin[] = "CURSOR=%08lX,%2X BIN"; char MSG_curs_dec[] = "CURSOR=%08lu,%2u DEC"; char MSG_curs_flt[] = "CURSOR=%08lu,%2u FLOAT"; char MSG_curs_oct[] = "CURSOR=%08lo,%2o OCTAL"; char MSG_print1[] = "Writing: %s; Hit Ctl-G to quit"; char MSG_print2[] = "Wrote %s lines"; char MSG_cnt_al_v[] = "ERROR: Cannot allocate memory fot VIDEO"; /* in ebcdic.c */ #if RUNCHK char ERR_ebcdic[] = "ERROR: Character %s not found in EBCDIC table\n"; #endif /* in echo.c */ char MSG_y_n[] = "%s [y/n]? "; char MSG_hit_key[] = " Hit Ctl-G to continue"; /* in extend.c */ char MSG_not_now[] = "Not now"; char MSG_func[] = "Function: "; char MSG_unk_func[] = "ERROR: Unknown function for binding"; char MSG_cmd_t_ex[] = "Command to execute: "; char MSG_unk_ext[] = "ERROR: Unknown extended command"; char MSG_unk_rc[] = "ERROR: Unknown rc command: "; char MSG_d_b[] = "Display key binding for which key? (hit key now!)"; char MSG_unbd[] = "%s is unbound"; char MSG_bnd_to[] = "%s is bound to %s"; char MSG_ins_self[] = "ins-self"; char MSG_bnd_file[] = "Binding file: "; char MSG_bld_wall[] = "Building help buffer"; char MSG_wall_head[] = "# Function name Key binding Key code"; char MSG_beavrc[] = "beavrc"; /* in file.c */ char MSG_rd_file[] = "Read file: "; char MSG_trash[] = "#tempbuf#"; char MSG_ins_file[] = "Insert file: "; char MSG_not_fnd[] = "Not found"; char MSG_visit[] = "Visit file: "; char MSG_view[] = "View file (read only): "; char MSG_buf_ex[] = "ERROR: Buffer exists"; char MSG_old_buf[] = "ERROR: Old buffer"; char MSG_cnt_cr[] = "ERROR: Cannot create buffer"; char MSG_reading[] = "reading <%s>"; char MSG_read_lx[] = "Read %s bytes, Hit Ctl-G to quit."; char MSG_no_mem_rd[] = "ERROR: Insufficient memory, buffer set to read only"; char MSG_wr_file[] = "Write file: "; char MSG_no_fn[] = "ERROR: No file name"; char MSG_bk_err[] = "ERROR: Backup error, save anyway"; char MSG_writing[] = "writing <%s>"; char MSG_wrot_n[] = "Wrote %s bytes, Hit Ctl-G to quit."; char MSG_fil_nam[] = "File name: "; #if RUNCHK char ERR_parse_fn[] = "ERROR: Starting address (%s) must preceede ending address (%s)"; char ERR_addr_neg[] = "ERROR: Addresses cannot be negative"; char ERR_f_size[] = "ERROR: Cannot access past end of file. (file size = %s)"; #endif /* in fileio.c */ char MSG_cnt_wr[] = "ERROR: Cannot open file for writing"; char MSG_wr_io_er[] = "ERROR: Write I/O error"; char MSG_rd_er[] = "ERROR: File read error"; #if UNIX char MSG_bak[] = ".~"; #else char MSG_bak[] = ".bak"; #endif char MSG_backup[] = "Back-up of %s to %s"; char MSG_back_er[] = "ERROR: Back-up of %s to %s FAILED !!"; char MSG_back_of[] = "%s - Back-up of <%s> to <%s>\n"; /* in kbd.c */ char MSG_tab[] = "Tab"; char MSG_ret[] = "Return"; char MSG_bksp[] = "Backspace"; char MSG_space[] = "Space"; char MSG_rubout[] = "Rubout"; /* in line.c */ char MSG_cnt_alloc[] = "ERROR: Cannot allocate %s bytes for a line"; char MSG_save_buf[] = "save-buffer"; /* in main.c */ char MSG_ok[] = "ok"; char MSG_no_mod[] = "ERROR: Buffer can not be modified"; char MSG_no_s_chg[] = "ERROR: Buffer size can not be changed"; char MSG_auto_fl[] = "Doing auto buffer flush"; char MSG_quit[] = "quit-no-save"; char MSG_st_mac[] = "Start macro"; char MSG_end_mac[] = "End macro"; char MSG_num_mod[] = "Number of modifcations per update: "; char version[] = "BEAV, Ver 1.40, March 31, 1993"; /* in random.c */ char MSG_sh_pos[] = "Cursor: %s, Mark: %s, Buffer Size: %s, File Size: %s"; char MSG_sh_pos1[] = "Cursor: %s, No Mark, Buffer Size: %s, File Size: %s"; char MSG_f_str[] = ", File: <%s>"; char MSG_lnk[] = "All windows on buffer <%s> are %s"; char MSG_unlink[] = "unlinked"; char MSG_link[] = "linked"; char MSG_bad_key[] = "ERROR: bad key = "; char MSG_esc[] = "Esc,"; char MSG_ctl_x[] = "Ctl-X,"; char MSG_ctl[] = "Ctl-"; char MSG_fn[] = "FN,"; char MSG_w_not_empty[] = "Destination buffer must be empty and modifiable"; char MSG_procing[] = "Processing at %s, Hit Ctl-G to quit."; char MSG_edit_float[] = "ERROR: Cannot edit floating point display."; /* in region.c */ char MSG_sv_in_b[] = "Save in buffer: "; char MSG_sav_slf[] = "ERROR: Can't save to self!"; /* in search.c */ char MSG_sch_str[] = " Search String"; char MSG_bsrc_str[] = "Back Search String"; char MSG_rpl_str[] = "Replace String"; char MSG_pat_fnd[] = "Pattern found at %s"; char MSG_no_srch[] = "ERROR: No last search"; char MSG_fnd_at[] = "Found at %s, (R)eplace, (S)kip, (A)ll, (O)ne, (Q)uit."; char MSG_no_rpl[] = "No replacements done"; char MSG_1_rpl[] = "1 replacement done"; char MSG_n_rpl[] = "%s replacements done"; char MSG_srcing[] = "Searching at %s, Hit Ctl-G to quit."; char MSG_curs[] = "%s; Curs = %s, %s Len = %s => "; char MSG_cmp_end[] = "Compare reached the end of a buffer"; char MSG_cmp_term[] = "Compare terminated by user"; char MSG_cmp_dif[] = "Difference is detected at the two cursor positions"; char MSG_only_2[] = "ERROR: There must be exactly two windows displayed to use Compare"; char MSG_cmping[] = "Comparing at %s, Hit Ctl-G to quit."; /* in spawn.c */ char MSG_shell[] = "COMSPEC"; char MSG_def_shell[] = "/command.com"; char MSG_pmpt[] = "PROMPT=[BEAV]"; char MSG_pt[] = "PROMPT"; char MSG_pme[] = "PROMPT="; /* in symbol.c */ char MSG_byte_shift[] = "display-byte-shift"; char MSG_back_char[] = "move-back-char"; char MSG_forw_del_char[] = "delete-forw-char"; char MSG_toggle_swap[] = "display-swap-order"; char MSG_forw_char[] = "move-forw-char"; char MSG_abort[] = "abort-cmd"; char MSG_back_del_char[] = "delete-back-char"; char MSG_refresh[] = "refresh-screen"; char MSG_forw_line[] = "move-forw-line"; char MSG_back_line[] = "move-back-line"; char MSG_quote[] = "insert-literally"; char MSG_recall[] = "recall-srch-string"; char MSG_twiddle[] = "unit-twiddle"; char MSG_forw_page[] = "move-forw-page"; char MSG_kill_region[] = "delete-mark-to-cursor"; char MSG_yank[] = "yank"; char MSG_down_window[] = "move-window-down"; char MSG_ins_toggle[] = "insert-toggle"; char MSG_display_buffers[] = "buffers-display"; char MSG_exit_flush_all[] = "quit-save-all"; char MSG_set_file_name[] = "buffer-set-file-name"; char MSG_file_insert[] = "insert-file"; char MSG_buf_size_lock[] = "buffer-size-lock"; char MSG_flush_all[] = "save-all-buffers"; char MSG_up_window[] = "move-window-up"; char MSG_file_read[] = "file-read"; char MSG_file_save[] = "file-save"; char MSG_file_visit[] = "file-visit"; char MSG_file_write[] = "file-write"; char MSG_swap_dot_and_mark[] = "swap-cursor-and-mark"; char MSG_shrink_window[] = "window-shrink"; char MSG_display_position[] = "show-position"; char MSG_start_macro[] = "macro-start"; char MSG_end_macro[] = "macro-end"; char MSG_help[] = "binding-for-key"; char MSG_only_window[] = "window-single"; char MSG_del_window[] = "window-delete"; char MSG_split_window[] = "window-split"; char MSG_scr_row[] = "screen-rows"; char MSG_use_buffer[] = "change-buffer"; char MSG_spawn_cli[] = "spawn-shell"; char MSG_execute_macro[] = "macro-execute"; char MSG_goto_line[] = "move-to-byte"; char MSG_ins_unit[] = "insert-unit"; char MSG_kill_buffer[] = "kill-buffer"; char MSG_load_bindings[] = "bindings-load"; char MSG_forw_window[] = "change-window-forw"; char MSG_back_window[] = "change-window-back"; char MSG_view_file[] = "file-view"; char MSG_enlarge_window[] = "window-enlarge"; char MSG_ascii_mode[] = "display-ascii"; char MSG_binary_mode[] = "display-binary"; char MSG_n_combine[] = "n-way-combine"; char MSG_buffer_name[] = "buffer-set-name"; char MSG_decimal_mode[] = "display-decimal"; char MSG_ebcdic_mode[] = "display-ebcdic"; char MSG_float_mode[] = "display-float"; char MSG_hex_mode[] = "display-hex"; char MSG_back_del_unit[] = "delete-back-unit"; char MSG_octal_mode[] = "display-octal"; char MSG_n_split[] = "n-way-split"; char MSG_display_version[] = "show-version"; char MSG_show_save_buf[] = "show-save-buf"; char MSG_unit_size1[] = "display-bytes"; char MSG_unit_size2[] = "display-words"; char MSG_unit_size4[] = "display-double-words"; char MSG_reposition_window[] = "window-reposition"; char MSG_set_mark[] = "mark-set"; char MSG_goto_eob[] = "move-to-end"; char MSG_goto_bob[] = "move-to-begining"; char MSG_next_buff[] = "change-to-next-buffer"; char MSG_prev_buff[] = "change-to-prev-buffer"; char MSG_query_replace[] = "replace"; char MSG_display_bindings[] = "help"; char MSG_auto_save[] = "auto-save"; char MSG_back_unit[] = "move-back-unit"; char MSG_compare[] = "compare"; char MSG_forw_del_unit[] = "delete-forw-unit"; char MSG_forw_unit[] = "move-forw-unit"; char MSG_link_windows[] = "window-link"; char MSG_print[] = "print-mark-to-cursor"; char MSG_back_search[] = "search-back"; char MSG_forw_search[] = "search-forw"; char MSG_back_page[] = "move-back-page"; char MSG_copy_region[] = "copy-mark-to-cursor"; char MSG_extended_command[] = "extended-command"; char MSG_search_again[] = "search-again"; char MSG_bind_to_key[] = "bind-to-key"; char MSG_file_visit_split[] = "file-visit-split"; char MSG_yank_buffer[] = "yank-buffer"; char MSG_save_region[] = "save-mark-to-cursor"; char MSG_use_buffer_split[] = "move-to-buffer-split"; char MSG_no_f_tb[] = "ERROR: Could not find <%s> in look up table\n"; /* in ttykbd.c */ char MSG_sp_key[] = "%u special keys bound\n"; /* in window.c */ char MSG_no_splt[] = "ERROR: Cannot split a %s line window"; char MSG_cnt_al_w[] = "ERROR: Cannot allocate WINDOW block"; char MSG_one_w[] = "ERROR: Only one window"; char MSG_imp_chg[] = "ERROR: Impossible change"; char MSG_scrn_rows[] = "Number of screen rows: "; #if RUNCHK /* in basic.c */ char ERR_bas_1[] = "ERROR: unknown r_type in basic #1"; /* in display.c */ char ERR_disp_1[] = "ERROR: unknown r_type in display #1"; char ERR_disp_2[] = "ERROR: unknown r_type in display #2"; char ERR_disp_3[] = "ERROR: row less than zero\n"; char ERR_disp_4[] = "ERROR: row greater then window size\n"; char ERR_disp_5[] = "ERROR: unknown r_type in display #3"; char ERR_disp_6[] = "ERROR: unknown r_size in display "; /* in line.c */ char ERR_no_alloc[] = "ERROR: new line was allocated during read pattern\n"; char ERR_db_dalloc[] = "ERROR: line was deallocated during read pattern\n"; char ERR_lock[] = "ERROR: This is size locked, cannot insert."; char ERR_lock_del[] = "ERROR: This is size locked, cannot delete."; /* in random.c */ char ERR_rnd_1[] = "ERROR: unknown r_type in random #1"; char ERR_rnd_2[] = "ERROR: unknown r_size in random #2"; char ERR_rnd_3[] = "ERROR: unknown r_type in random #3"; char ERR_rnd_4[] = "ERROR: unknown r_size in random #4"; char ERR_rnd_5[] = "ERROR: unknown r_size in random #5"; char ERR_rnd_6[] = "ERROR: unknown r_size in random #6"; char ERR_rnd_7[] = "ERROR: unknown r_size in random #7"; /* in search.c */ char ERR_rdpat[] = "ERROR: bad r_type in readpattern\n"; char ERR_mask[] = "ERROR: size of mask pattern, pat=%d, mask=%d\n"; char ERR_m_cl[] = "ERROR: in ascii mode mask byte was not cleared\n"; /* in ttyio.c */ char ERR_bd_pl[] = "ERROR: bad call to putline\n"; #endif beav-140/line.c0000644000175000001440000003323505667134707013354 0ustar samusers00000000000000/* * Text line handling. * The functions in this file * are a general set of line management * utilities. They are the only routines that * touch the text. They also touch the buffer * and window structures, to make sure that the * necessary updating gets done. There are routines * in this file that handle the kill buffer too. * It isn't here for any good reason. * * Note that this code only updates the dot and * mark values in the window list. Since all the code * acts on the current window, the buffer that we * are editing must be being displayed, which means * that "b_nwnd" is non zero, which means that the * dot and mark values in the buffer headers are * nonsense. */ #include "def.h" void l_fix_up (); extern char MSG_cnt_alloc[]; #if RUNCHK extern char ERR_no_alloc[]; extern char ERR_db_dalloc[]; extern char ERR_lock[]; extern char ERR_lock_del[]; #endif extern LINE *cur_pat; extern LINE *cur_mask; extern bool read_pat_mode; extern BUFFER sav_buf; /* * This routine allocates a block * of memory large enough to hold a LINE * containing "size" characters. Return a pointer * to the new block, or NULL if there isn't * any memory left. Print a message in the * message line if no space. */ LINE * lalloc (size) register int size; { register LINE *lp; char buf[NCOL], buf1[NCOL]; #if RUNCHK if (read_pat_mode) printf (ERR_no_alloc); #endif if ((lp = (LINE *) malloc (sizeof (LINE) + size)) == NULL) { sprintf (buf1, MSG_cnt_alloc, R_POS_FMT (curwp)); sprintf (buf, buf1, (A32) size); err_echo (buf); curbp->b_flag |= BFBAD; /* may be trashed */ curwp->w_flag |= WFMODE; update (); return (NULL); } lp->l_size = size; lp->l_used = 0; lp->l_file_offset = 0; /* set resonable initial value */ return (lp); } /* * Delete line "lp". Fix all of the * links that might point at it (they are * moved to offset 0 of the next line. * Unlink the line from whatever buffer it * might be in. Release the memory. The * buffers are updated too; the magic conditions * described in the above comments don't hold * here. */ void lfree (lp) register LINE *lp; { register BUFFER *bp; register WINDOW *wp; #if RUNCHK if (read_pat_mode) printf (ERR_db_dalloc); #endif wp = wheadp; while (wp != NULL) { if (wp->w_linep == lp) { wp->w_linep = lp->l_fp; wp->w_loff = 0; } if (wp->w_dotp == lp) { wp->w_dotp = lp->l_fp; wp->w_doto = 0; } if (wp->w_markp == lp) { wp->w_markp = lp->l_fp; wp->w_marko = 0; } wp = wp->w_wndp; } bp = bheadp; while (bp != NULL) { if (bp->b_nwnd == 0) { if (bp->b_dotp == lp) { bp->b_dotp = lp->l_fp; bp->b_doto = 0; } if (bp->b_markp == lp) { bp->b_markp = lp->l_fp; bp->b_marko = 0; } } bp = bp->b_bufp; } lp->l_bp->l_fp = lp->l_fp; lp->l_fp->l_bp = lp->l_bp; free ((char *) lp); } /* * This routine gets called when * a character is changed in place in the * current buffer. It updates all of the required * flags in the buffer and window system. The flag * used is passed as an argument; if the buffer is being * displayed in more than 1 window we change EDIT to * HARD. Set MODE if the mode line needs to be * updated (the "*" has to be set). */ void lchange (flag) register int flag; { register WINDOW *wp; if (curbp->b_nwnd != 1) /* Ensure hard. */ flag = WFHARD; if ((curbp->b_flag & BFCHG) == 0) { /* First change, so */ flag |= WFMODE; /* update mode lines. */ curbp->b_flag |= BFCHG; } wp = wheadp; while (wp != NULL) { if (wp->w_bufp == curbp) wp->w_flag |= flag; wp = wp->w_wndp; } } /* * Break the line "dotp" in two at the position "doto." */ LINE * l_break_in_two (lp, lo, extra) register LINE *lp; register LPOS lo, extra; { register LINE *new_lp; register D8 *cp1; register D8 *cp2; LPOS cnt, i; i = 0; cnt = lp->l_used - lo; if ((new_lp = lalloc (cnt + extra)) == NULL) return (NULL); cp1 = &lp->l_text[lo]; /* starting location, source */ cp2 = &new_lp->l_text[0]; /* starting location, destination */ /* kill bytes in the current line */ while (i++ < cnt) { *cp2++ = *cp1++; } lp->l_used -= cnt; new_lp->l_used = cnt; new_lp->l_file_offset = new_lp->l_file_offset + lo; /* insert into chain */ new_lp->l_fp = lp->l_fp; lp->l_fp = new_lp; new_lp->l_bp = lp; new_lp->l_fp->l_bp = new_lp; return (new_lp); } /* * Insert "n" copies of the character "c" * at the current location of dot. In the easy case * all that happens is the text is stored in the line. * Always allocate some extra space in line so that edit * will be faster next time but will save space in the general case. * In the hard case, the line has to be reallocated. * When the window list is updated, take special * care; I screwed it up once. You always update dot * in the current window. You update mark, and a * dot in another window, if it is greater than * the place where you did the insert. Return TRUE * if all is well, and FALSE on errors. */ bool linsert (n, c) uchar c; int n; { register D8 *cp1; register D8 *cp2; register LINE *lp1; register LINE *lp2; register short doto; register int i; register WINDOW *wp; #if RUNCHK /* check that buffer size can be changed */ if (curbp->b_flag & BFSLOCK) { writ_echo (ERR_lock); return (FALSE); } #endif lchange (WFMOVE); lp1 = curwp->w_dotp; /* Current line */ if (lp1 == curbp->b_linep) { /* At the end: special */ /* break the current line at the end */ if ((lp2 = l_break_in_two (lp1, lp1->l_used, (LPOS) n + NBLOCK)) == NULL) return (FALSE); for (i = 0; i < n; ++i) /* Add the characters */ lp2->l_text[i] = c; lp2->l_used = n; curwp->w_dotp = lp2; curwp->w_doto = n; return (TRUE); } doto = curwp->w_doto; /* Save for later. */ if (lp1->l_used + n > lp1->l_size) { /* break the current line and let the normal insert do it */ if ((lp2 = l_break_in_two (lp1, doto, (LPOS) n + NBLOCK)) == NULL) return (FALSE); lp1->l_text[doto] = c; lp1->l_used++; curwp->w_doto++; if (curwp->w_doto >= lp1->l_used) { curwp->w_dotp = lp2; curwp->w_doto = 0; } if (n > 1) return (linsert (n - 1, c)); /* handle the rest in normal maner */ } else { /* Easy: in place */ lp2 = lp1; /* Pretend new line */ lp2->l_used += n; cp2 = &lp1->l_text[lp1->l_used]; cp1 = cp2 - n; while (cp1 != &lp1->l_text[doto]) *--cp2 = *--cp1; for (i = 0; i < n; ++i) /* Add the characters */ lp2->l_text[doto + i] = c; move_ptr (curwp, (A32) n, TRUE, TRUE, TRUE); } wp = wheadp; /* Update windows */ while (wp != NULL) { if ((wp->w_linep == lp1) && (wp->w_loff >= lp1->l_used)) { wp->w_linep = lp2; wp->w_loff -= lp1->l_used; } /* move dot to next line but not to head line */ if ((wp->w_dotp == lp1) && (wp->w_doto >= lp1->l_used) && (wp->w_dotp->l_fp->l_size != 0)) { wp->w_dotp = lp2; wp->w_doto -= (lp1->l_used - 1); } if ((wp->w_markp == lp1) && (wp->w_marko >= lp1->l_used)) { wp->w_markp = lp2; wp->w_marko -= (lp1->l_used - 1); } wp = wp->w_wndp; } l_fix_up (lp1); /* re-adjust file offsets */ return (TRUE); } /* * This function deletes n_bytes, * starting at dot. It understands how to deal * with end of lines, etc. It returns TRUE if all * of the characters were deleted, and FALSE if * they were not (because dot ran into the end of * the buffer). The "kflag" is TRUE if the text * should be put in the kill buffer. */ bool ldelete (n_bytes, kflag) A32 n_bytes; int kflag; { register LINE *dotp, *lp, *lp_prev, *lp_next; register LPOS doto, l_cnt; register WINDOW *wp; D8 *cp1, *cp2; D32 dot_pos; uint n_byt; #if RUNCHK /* check that buffer size can be changed */ if (curbp->b_flag & BFSLOCK) { writ_echo (ERR_lock_del); return (FALSE); } #endif lchange (WFMOVE); doto = curwp->w_doto; dotp = curwp->w_dotp; lp_prev = dotp->l_bp; dot_pos = DOT_POS (curwp); /* if at the end of the buffer then delete nothing */ if (dot_pos >= BUF_SIZE (curwp)) { l_fix_up (dotp); /* re-adjust file offsets */ return (TRUE); } /* save dot and mark positions for later restore */ wp = wheadp; while (wp != NULL) { wp->w_dot_temp = DOT_POS (wp); if (wp->w_markp != NULL)/* mark may not be set */ wp->w_mark_temp = MARK_POS (wp); wp->w_wind_temp = WIND_POS (wp); wp = wp->w_wndp; } /* is delete wholy within one line? */ if ((doto + n_bytes) <= dotp->l_used) { cp1 = &dotp->l_text[doto]; /* Scrunch text. */ cp2 = cp1 + n_bytes; /* put stuff to delete into the kill buffer */ if (kflag != FALSE) { /* Kill? */ while (cp1 != cp2) { if (b_append_c (&sav_buf, *cp1) == FALSE) return (FALSE); ++cp1; } cp1 = &dotp->l_text[doto]; } /* kill bytes in the current line */ while (cp2 < &dotp->l_text[dotp->l_used]) *cp1++ = *cp2++; dotp->l_used -= n_bytes; } else { /* wholesale delete by moving lines to save buffer */ if (doto != 0) { if ((lp = l_break_in_two (dotp, doto, 0)) == NULL) return (FALSE); } else lp = dotp; n_byt = n_bytes; /* now handle whole lines if necessary */ while (n_byt > 0) { lp_next = lp->l_fp; if (n_byt < lp->l_used) { /* get last piece of a line */ lp_next = l_break_in_two (lp, n_byt, 0); } n_byt -= lp->l_used; if (kflag) { /* remove form linked list */ lp->l_bp->l_fp = lp->l_fp; lp->l_fp->l_bp = lp->l_bp; /* append it to the save buffer */ b_append_l (&sav_buf, lp); } else /* if we don't want it, free it */ lfree (lp); lp = lp_next; } } l_fix_up (lp_prev); /* re-adjust file offsets */ /* adjust dot and marks in other windows */ /* this should be ok because the save buffer dosn't disturb l_file_offset */ wp = wheadp; /* Fix windows */ while (wp != NULL) { if (curbp == wp->w_bufp) { A32 temp; /* if dot is before delete position, do nothing */ if (dot_pos <= (temp = wp->w_dot_temp)) { /* step back to the previous line */ wp->w_doto = 0; wp->w_dotp = lp_prev; /* if dot is in deleted range, set to dot position */ if (temp > dot_pos + n_bytes) /* if after deleted range, move back deleted ammount */ move_ptr (wp, temp - n_bytes, TRUE, TRUE, FALSE); else /* if in the deleted range, move to curwp dot position */ move_ptr (wp, dot_pos, TRUE, TRUE, FALSE); } /* mark may not be set in some windows */ if (wp->w_markp != NULL) { /* do the same for mark */ if (dot_pos <= (temp = wp->w_mark_temp)) { /* if in or after the deleted range, move to curwp dot position */ wp->w_marko = curwp->w_doto; wp->w_markp = curwp->w_dotp; /* if mark after deleted range */ if (temp > dot_pos + n_bytes) { /* if after deleted range, move back deleted ammount */ /* move dot then swap with mark to produce result */ move_ptr (wp, temp - n_bytes, TRUE, TRUE, FALSE); lp_next = wp->w_dotp; wp->w_dotp = wp->w_markp; wp->w_markp = lp_next; l_cnt = wp->w_doto; wp->w_doto = wp->w_marko; wp->w_marko = l_cnt; } } } /* if window position is before delete position, do nothing */ if (dot_pos <= (temp = wp->w_wind_temp)) { /* set window position to dot position */ wp->w_loff = 0; wp->w_linep = wp->w_dotp; wind_on_dot (wp); } } wp = wp->w_wndp; } /* update buffer display */ if ((blistp->b_nwnd != 0) && (blistp->b_type == BTLIST)) listbuffers (); return (TRUE); } /* * Replace character at dot position. */ void lreplace (n, c) int n; char c; { lchange (WFEDIT); while (n--) { DOT_CHAR (curwp) = c & 0xff; move_ptr (curwp, 1L, TRUE, FALSE, TRUE); } } /* * Replace plen characters before dot with argument string. */ bool lrepl_str (plen, rstr, mstr) register int plen; /* length to remove */ register LINE *rstr; /* replace string */ register LINE *mstr; /* mask string */ { register int i; /* used for random characters */ register A32 dot_pos; /* dot offset into buffer */ register int rlen; /* rplace string length */ register char c; /* temp storage for char */ register char mask; /* temp storage for mask */ /* * make the string lengths match (either pad the line * so that it will fit, or scrunch out the excess). * be careful with dot's offset. */ /* get offset from begining of buffer */ dot_pos = DOT_POS (curwp); rlen = rstr->l_used; if (plen > rlen) { ldelete ((A32) (plen - rlen), FALSE); } else if (plen < rlen) { if (linsert (rlen - plen, ' ') == FALSE) return (FALSE); } /* must use move_ptr because delete may advance to next line */ move_ptr (curwp, dot_pos, TRUE, FALSE, FALSE); /* do the replacement. */ for (i = 0; i < rlen; i++) { c = DOT_CHAR (curwp); mask = mstr->l_text[i]; DOT_CHAR (curwp) = (c & mask) | (rstr->l_text[i] & ~mask); move_ptr (curwp, 1L, TRUE, FALSE, TRUE); } move_ptr (curwp, dot_pos, TRUE, FALSE, FALSE); lchange (WFHARD); return (TRUE); } /* * Line fixup. * This fixes the 'l_file_offset' variable in * each line structure. * This is necessary after every change in the size * of the buffer. */ void l_fix_up (line) LINE *line; /* points to buffer header line */ { long offset; offset = line->l_file_offset; /* starting offset */ offset += line->l_used; for (;;) { line = line->l_fp; if (line->l_size == 0) return; line->l_file_offset = offset; offset += line->l_used; } } beav-140/main.c0000644000175000001440000002660505667134707013354 0ustar samusers00000000000000/* * 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 and MSC 5.1 under DOS. The old Wang PC is * supported. This release is for unix. The def_unix.h file is the * header for unix and the def_dos.h file is the header for dos. Rename * the appropriate .h file to def.h to convert to your os. * 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 */ /* * Bug fix log * 3/04/91 1.20 pvr * Create new file with read/write permisions. * Fix polled mode system hog tty bug. * Add ANSI define for DOS. * Define short for D16 type. * Call ttclose on error exit. * Limit nrow and ncol to actual array size. * Added beavrc key binding functionallity. * Added delete current window command. * Support VT100 type function keys for binding. */ /* * * Mainline, macro commands. */ #include "def.h" bool execute (); void edinit (); char flush_all (); char quit (); char ctrlg (); void _lowercase (); extern char MSG_ok[]; extern char MSG_main[]; extern char MSG_prog_name[]; extern char MSG_init_file[]; extern char MSG_init_var[]; extern char MSG_init_path[]; extern char MSG_no_mod[]; extern char MSG_no_s_chg[]; extern char MSG_auto_fl[]; extern char MSG_quit[]; extern char MSG_not_now[]; extern char MSG_st_mac[]; extern char MSG_end_mac[]; extern char MSG_num_mod[]; extern char MSG_null[]; int thisflag; /* Flags, this command */ int lastflag; /* Flags, last command */ int curgoal; /* Goal column */ int com_line_flags; /* Count of cmd line switches */ BUFFER *curbp; /* Current buffer */ WINDOW *curwp; /* Current window */ BUFFER *bheadp; /* BUFFER listhead */ WINDOW *wheadp; /* WINDOW listhead */ BUFFER *blistp; /* Buffer list BUFFER */ short kbdm[NKBDM] = { (KCTLX | ')')}; /* Macro (fitz) */ short *kbdmip; /* Input for above */ short *kbdmop; /* Output for above */ SYMBOL *symbol[NSHASH]; /* Symbol table listhead. */ SYMBOL *binding[NKEYS]; /* Key bindings. */ extern ROW_FMT hex_8_fmt; extern bool ibm_pc, mem_map; char *okmsg = { MSG_ok}; int insert_mode = { TRUE}; int extend_buf = { FALSE}; extern bool srch_mode; extern bool rplc_mode; extern char *getenv (); int initial_load = 0; int flush_count = 0; int flush_num = 500; int auto_update = 0; void main (argc, argv) char *argv[]; int argc; { register int c; register int f; register int n; register int mflag; char bname[NBUFN]; char initfile[NFILEN]; #if MSDOS is_wang (); /* Check for computer type */ #endif init_fmt (); /* initialize format arrays */ strcpy (bname, MSG_main); /* Get buffer name. */ ttopen (); /* set default screen size */ ttinit (); /* set terminal raw mode */ vtinit (); /* Virtual terminal. */ keymapinit (); /* Symbols, bindings. */ #ifdef OS2 #ifdef __EMX__ _response (&argc, &argv); _wildcard (&argc, &argv); #endif _searchenv (MSG_init_file, MSG_init_var, initfile); if (initfile[0]) check_extend (initfile); else { _searchenv (MSG_init_file, MSG_init_path, initfile); if (initfile[0]) check_extend (initfile); else check_extend (getenv (MSG_prog_name)); } #else check_extend (NULL); /* check for extended keys */ #endif if (argc == 1) { edinit (bname); eerase (); update (); } else { com_line_flags = 0; initial_load = 1; n = (argc - 1); /* Load them backwards */ if (n > com_line_flags) { /* _lowercase (argv[n]); */ makename (bname, argv[n]); edinit (bname); /* Buffers, windows. */ eerase (); update (); readin (argv[n--], 0L, MAXPOS); for (; n > com_line_flags; n--) { /* _lowercase (argv[n]); */ load_file (argv[n], 0L, MAXPOS); } } else { edinit (bname); eerase (); update (); } initial_load = 0; } save_buf_init (); /* initialize save buffer */ lastflag = 0; /* Fake last flags. */ loop: update (); c = getkey (); if (epresf != FALSE) { eerase (); update (); } f = FALSE; n = 1; if (c == (KCTRL | 'U')) { /* ^U, start argument. */ f = TRUE; n = 4; while ((c = getkey ()) == (KCTRL | 'U')) n *= 4; if ((c >= '0' && c <= '9') || c == '-') { if (c == '-') { n = 0; mflag = TRUE; } else { n = c - '0'; mflag = FALSE; } while ((c = getkey ()) >= '0' && c <= '9') n = 10 * n + c - '0'; if (mflag != FALSE) n = -n; } } if (kbdmip != NULL) { /* Save macro strokes. */ if (c != (KCTLX | ')') && kbdmip > &kbdm[NKBDM - 6]) { ctrlg (FALSE, 0, KRANDOM); goto loop; } if (f != FALSE) { *kbdmip++ = (KCTRL | 'U'); *kbdmip++ = n; } *kbdmip++ = c; } execute (c, f, n); /* Do it. */ goto loop; } /* * Command execution. Look up the binding in the the * binding array, and do what it says. Return a very bad status * if there is no binding, or if the symbol has a type that * is not usable (there is no way to get this into a symbol table * entry now). Also fiddle with the flags. */ char execute (c, f, n) int c, f, n; { register SYMBOL *sp; register int status; if ((sp = binding[c]) != NULL) { thisflag = 0; if (sp->s_modify & SMOD && (curbp->b_flag & BFVIEW)) { writ_echo (MSG_no_mod); return (ABORT); } if (sp->s_modify & SSIZE && (curbp->b_flag & BFSLOCK)) { writ_echo (MSG_no_s_chg); return (ABORT); } if ((srch_mode && !(sp->s_modify & SSRCH)) || (rplc_mode && !(sp->s_modify & SRPLC))) { ttbeep (); return (TRUE); } status = (*sp->s_funcp) (f, n, c); if (sp->s_modify & SMOD) flush_count++; if (flush_count >= flush_num && auto_update) if (!(kbdmip != NULL || kbdmop != NULL)) /* not during macro */ { ttbeep (); writ_echo (MSG_auto_fl); flush_all (); } lastflag = thisflag; return (status); } else bad_key (c); lastflag = 0; return (ABORT); } /* * Initialize all of the buffers * and windows. The buffer name is passed down as * an argument, because the main routine may have been * told to read in a file by default, and we want the * buffer name to be right. */ void edinit (bname) char bname[]; { register BUFFER *bp; register WINDOW *wp; bp = bfind (bname, TRUE); /* Text buffer. */ blistp = bcreate (MSG_null);/* Special list buffer. */ wp = (WINDOW *) malloc (sizeof (WINDOW)); /* Initial window. */ if (bp == NULL || wp == NULL || blistp == NULL) abort (); curbp = bp; /* Current ones. */ wheadp = wp; curwp = wp; wp->w_wndp = NULL; /* Initialize window. */ wp->w_bufp = bp; bp->b_nwnd = 1; /* Displayed. */ wp->w_fmt_ptr = &hex_8_fmt; /* HEX 8 bit display pvr */ wp->w_linep = bp->b_linep; wp->w_dotp = bp->b_linep; wp->w_doto = 0; /* set dot pos pvr */ wp->w_markp = NULL; wp->w_marko = 0; wp->w_toprow = 0; wp->w_ntrows = nrow - 2; /* 2 = mode, echo. */ wp->w_flag = WFMODE | WFHARD; /* Full. */ wp->w_intel_mode = FALSE; /* default is no byte swap pvr */ wp->w_disp_shift = 0; /* default to no byte shift pvr */ wp->w_loff = 0; /* starting line offset pvr */ wp->w_unit_offset = 0; /* dot offset from file start pvr */ } /* * Flush all the dirty buffers that have file names * associated with them. */ char flush_all () { register BUFFER *bp, *savbp = curbp; for (bp = bheadp; bp != NULL; bp = bp->b_bufp) if (bp->b_fname != NULL) { curbp = bp; /* jam */ filesave (); update (); } flush_count = 0; writ_echo (okmsg); curbp = savbp; if (blistp->b_nwnd != 0) /* update buffer display */ listbuffers (); update (); return (TRUE); } /* call flush_all to empty the buffers * and quit */ bool flushnquit (f, n, k) int f, n, k; { flush_all (); quit (f, n, k); return (TRUE); } /* * Quit command. If an argument, always * quit. Otherwise confirm if a buffer has been * changed and not written out. Normally bound * to "C-X C-C". */ char quit (f, n, k) int f, n, k; { register char s; if (f != FALSE /* Argument forces it. */ || anycb () == FALSE /* All buffers clean. */ || (s = eyesno (MSG_quit)) == TRUE) /* User says it's OK. */ { vttidy (); exit (GOOD); } return (s); } /* * Begin a keyboard macro. * Error if not at the top level * in keyboard processing. Set up * variables and return. */ bool ctlxlp (f, n, k) int f, n, k; { if (kbdmip != NULL || kbdmop != NULL) { writ_echo (MSG_not_now); return (FALSE); } writ_echo (MSG_st_mac); kbdmip = &kbdm[0]; return (TRUE); } /* * End keyboard macro. Check for * the same limit conditions as the * above routine. Set up the variables * and return to the caller. */ bool ctlxrp (f, n, k) int f, n, k; { if (kbdmip == NULL) { writ_echo (MSG_not_now); return (FALSE); } writ_echo (MSG_end_mac); kbdmip = NULL; return (TRUE); } /* * Execute a macro. * The command argument is the * number of times to loop. Quit as * soon as a command gets an error. * Return TRUE if all ok, else * FALSE. */ bool ctlxe (f, n, k) int f, n, k; { register int c; register int af; register int an; register int s; if (kbdmip != NULL || kbdmop != NULL) { writ_echo (MSG_not_now); return (FALSE); } if (n <= 0) return (TRUE); do { kbdmop = &kbdm[0]; do { af = FALSE; an = 1; if ((c = *kbdmop++) == (KCTRL | 'U')) { af = TRUE; an = *kbdmop++; c = *kbdmop++; } s = TRUE; } while (c != (KCTLX | ')') && (s = execute (c, af, an)) == TRUE); kbdmop = NULL; } while (s == TRUE && --n); return (s); } /* * Abort. * Beep the beeper. * Kill off any keyboard macro, * etc., that is in progress. * Sometimes called as a routine, * to do general aborting of * stuff. */ char ctrlg (f, n, k) int f, n, k; { /* ttbeep (); */ if (kbdmip != NULL) { kbdm[0] = (KCTLX | ')'); kbdmip = NULL; } return (ABORT); } /* * Display the version. All this does * is copy the text in the external "version" array into * the message system, and call the message reading code. * Don't call display if there is an argument. */ char showversion (f, n, k) int f, n, k; { static char *cp; char buf[NCOL]; cp = version; sprintf (buf, cp); writ_echo (buf); return (TRUE); } /* ughly to_lower function for * files read in under MSDOS setargv function */ void _lowercase (s) register char *s; { #ifdef MSDOS for (; *s; s++) if (ISUPPER (*s)) *s = TOLOWER (*s); #endif } /* autosave control */ bool autosave () { register WINDOW *wp; int n; char buf[NCOL]; if ((ereply (MSG_num_mod, buf, sizeof (buf), NULL)) == TRUE) { n = atoi (buf); if (n >= 0) auto_update = flush_num = n; /* not 0! */ else auto_update = 0; } for (wp = wheadp; wp; wp = wp->w_wndp) if (wp->w_bufp == curbp) wp->w_flag |= WFMODE; return (TRUE); } beav-140/makefile.2860000644000175000001440000000127405667134707014275 0ustar samusers00000000000000# This is a makefile for 286 xenix CFLAGS= -O -Ml -DUNIX -DNOPROTO -DNORENAME OFILES= basic.o ebcdic.o fileio.o region.o text.o wangpc.o \ language.obj buffer.o echo.o main.o search.o tty.o window.o \ cinfo.o extend.o kbd.o spawn.o ttyio.o termio.o tcap.o word.o \ display.o file.o line.o random.o symbol.o ttykbd.o format.o CFILES= basic.c ebcdic.c fileio.c region.c text.c wangpc.c \ buffer.c echo.c language.c format.c main.c search.c tty.c window.c \ cinfo.c extend.c kbd.c spawn.c ttyio.c termio.c tcap.c word.c \ display.c file.c line.c random.c symbol.c ttykbd.c HFILES= def.h beav: $(OFILES) $(CC) $(CFLAGS) $(OFILES) -ltermcap -lc -o beav (OFILES): $(HFILES) beav-140/makefile.amg0000644000175000001440000000114305667134707014515 0ustar samusers00000000000000# # Makefile for commodore amiga version of beav, SAS C V5.10a, SJR Jun 1991. # # Modifications #--------------- # # 21st August 1991 - Version 1.32 - SJR # # CFLAGS= -cw -j93i85i -DNOPROTO -DANSI CC= lc OFILES= amiga.o basic.o ebcdic.o fileio.o region.o text.o wangpc.o \ buffer.o echo.o language.o main.o search.o tty.o window.o \ cinfo.o extend.o kbd.o spawn.o ttyio.o termio.o tcap.o word.o \ display.o file.o line.o random.o symbol.o ttykbd.o format.o # If using SAS LMK comment out the following line HFILES= def.h beav: $(OFILES) blink with amibeav.lnk # protect $@ add p $(OFILES): $(HFILES) beav-140/makefile.bsd0000644000175000001440000000125005667134707014520 0ustar samusers00000000000000# This is the makefile for BSD UNIX CFLAGS= -O -DUNIX -DBSD -DNOPROTO OFILES= basic.o ebcdic.o fileio.o region.o text.o wangpc.o \ buffer.o echo.o language.o main.o search.o tty.o window.o \ cinfo.o extend.o kbd.o spawn.o ttyio.o termio.o tcap.o word.o \ display.o file.o line.o random.o symbol.o ttykbd.o format.o CFILES= basic.c ebcdic.c fileio.c region.c text.c wangpc.c \ buffer.c echo.c language.c main.c search.c tty.c window.c \ cinfo.c extend.c kbd.c spawn.c ttyio.c termio.c tcap.c word.c \ display.c file.c line.c random.c symbol.c ttykbd.c HFILES= def.h beav: $(OFILES) $(CC) $(CFLAGS) $(OFILES) -ltermcap -lc -o beav (OFILES): $(HFILES) beav-140/makefile.mc50000644000175000001440000000367305667134707014447 0ustar samusers00000000000000# makefile for BEAV under MSDOS using Microsoft MSC 5.1 BASIC.OBJ: BASIC.C DEF.H PROTOTYP.H CL -c -Ml BASIC.C ; BUFFER.OBJ: BUFFER.C DEF.H PROTOTYP.H CL -c -Ml BUFFER.C ; CINFO.OBJ: CINFO.C DEF.H PROTOTYP.H CL -c -Ml CINFO.C ; DISPLAY.OBJ: DISPLAY.C DEF.H PROTOTYP.H CL -c -Ml DISPLAY.C ; EBCDIC.OBJ: EBCDIC.C DEF.H PROTOTYP.H CL -c -Ml EBCDIC.C ; ECHO.OBJ: ECHO.C DEF.H PROTOTYP.H CL -c -Ml ECHO.C ; EXTEND.OBJ: EXTEND.C DEF.H PROTOTYP.H CL -c -Ml EXTEND.C ; FILE.OBJ: FILE.C DEF.H PROTOTYP.H CL -c -Ml FILE.C ; FILEIO.OBJ: FILEIO.C DEF.H PROTOTYP.H CL -c -Ml FILEIO.C ; FORMAT.OBJ: FORMAT.C DEF.H PROTOTYP.H CL -c -Ml FORMAT.C ; KBD.OBJ: KBD.C DEF.H PROTOTYP.H CL -c -Ml KBD.C ; LANGUAGE.OBJ: LANGUAGE.C DEF.H PROTOTYP.H CL -c -Ml LANGUAGE.C ; LINE.OBJ: LINE.C DEF.H PROTOTYP.H CL -c -Ml LINE.C ; MAIN.OBJ: MAIN.C DEF.H PROTOTYP.H CL -c -Ml MAIN.C ; RANDOM.OBJ: RANDOM.C DEF.H PROTOTYP.H CL -c -Ml RANDOM.C ; REGION.OBJ: REGION.C DEF.H PROTOTYP.H CL -c -Ml REGION.C ; SEARCH.OBJ: SEARCH.C DEF.H PROTOTYP.H CL -c -Ml SEARCH.C ; SPAWN.OBJ: SPAWN.C DEF.H PROTOTYP.H CL -c -Ml SPAWN.C ; SYMBOL.OBJ: SYMBOL.C DEF.H PROTOTYP.H CL -c -Ml SYMBOL.C ; TEXT.OBJ: TEXT.C DEF.H PROTOTYP.H CL -c -Ml TEXT.C ; TTY.OBJ: TTY.C DEF.H PROTOTYP.H CL -c -Ml TTY.C ; TTYIO.OBJ: TTYIO.C DEF.H PROTOTYP.H CL -c -Ml TTYIO.C ; TTYKBD.OBJ: TTYKBD.C DEF.H PROTOTYP.H CL -c -Ml TTYKBD.C ; WANGPC.OBJ: WANGPC.C DEF.H PROTOTYP.H CL -c -Ml WANGPC.C ; WINDOW.OBJ: WINDOW.C DEF.H PROTOTYP.H CL -c -Ml WINDOW.C ; WORD.OBJ: WORD.C DEF.H PROTOTYP.H CL -c -Ml WORD.C ; BEAV.EXE: BASIC.OBJ BUFFER.OBJ CINFO.OBJ DISPLAY.OBJ ECHO.OBJ EXTEND.OBJ \ EBCDIC.OBJ FILE.OBJ FILEIO.OBJ FORMAT.OBJ KBD.OBJ LINE.OBJ \ LANGUAGE.OBJ MAIN.OBJ RANDOM.OBJ TEXT.OBJ \ REGION.OBJ SEARCH.OBJ SPAWN.OBJ SYMBOL.OBJ TTY.OBJ TTYIO.OBJ \ TTYKBD.OBJ WINDOW.OBJ WORD.OBJ WANGPC.OBJ LINK @beav.lnk beav-140/makefile.mc70000644000175000001440000000464205667134707014446 0ustar samusers00000000000000# makefile for BEAV under MSDOS using Microsoft MSC 7.0 CFLAGS = /c /Ml #CFLAGS = /c /Ml /Gs /Zi all : BASIC.OBJ BUFFER.OBJ CINFO.OBJ DISPLAY.OBJ EBCDIC.OBJ all : ECHO.OBJ EXTEND.OBJ FILE.OBJ FILEIO.OBJ FORMAT.OBJ all : KBD.OBJ LINE.OBJ MAIN.OBJ RANDOM.OBJ REGION.OBJ SEARCH.OBJ all : SPAWN.OBJ SYMBOL.OBJ TEXT.OBJ TTY.OBJ TTYKBD.OBJ TTYIO.OBJ all : WANGPC.OBJ WINDOW.OBJ WORD.OBJ BEAV.EXE prototyp: CL -Zg *.C > proto.h del prototyp.h ren proto.h prototyp.h BASIC.OBJ: BASIC.C DEF.H PROTOTYP.H CL $(CFLAGS) BASIC.C BUFFER.OBJ: BUFFER.C DEF.H PROTOTYP.H CL $(CFLAGS) BUFFER.C ; CINFO.OBJ: CINFO.C DEF.H PROTOTYP.H CL $(CFLAGS) CINFO.C ; DISPLAY.OBJ: DISPLAY.C DEF.H PROTOTYP.H CL $(CFLAGS) DISPLAY.C ; EBCDIC.OBJ: EBCDIC.C DEF.H PROTOTYP.H CL $(CFLAGS) EBCDIC.C ; ECHO.OBJ: ECHO.C DEF.H PROTOTYP.H CL $(CFLAGS) ECHO.C ; EXTEND.OBJ: EXTEND.C DEF.H PROTOTYP.H CL $(CFLAGS) EXTEND.C ; FILE.OBJ: FILE.C DEF.H PROTOTYP.H CL $(CFLAGS) FILE.C ; FILEIO.OBJ: FILEIO.C DEF.H PROTOTYP.H CL $(CFLAGS) FILEIO.C ; FORMAT.OBJ: FORMAT.C DEF.H PROTOTYP.H CL $(CFLAGS) FORMAT.C ; KBD.OBJ: KBD.C DEF.H PROTOTYP.H CL $(CFLAGS) KBD.C ; LANGUAGE.OBJ: LANGUAGE.C DEF.H PROTOTYP.H CL $(CFLAGS) LANGUAGE.C ; LINE.OBJ: LINE.C DEF.H PROTOTYP.H CL $(CFLAGS) LINE.C ; MAIN.OBJ: MAIN.C DEF.H PROTOTYP.H CL $(CFLAGS) MAIN.C ; RANDOM.OBJ: RANDOM.C DEF.H PROTOTYP.H CL $(CFLAGS) RANDOM.C ; REGION.OBJ: REGION.C DEF.H PROTOTYP.H CL $(CFLAGS) REGION.C ; SEARCH.OBJ: SEARCH.C DEF.H PROTOTYP.H CL $(CFLAGS) SEARCH.C ; SPAWN.OBJ: SPAWN.C DEF.H PROTOTYP.H CL $(CFLAGS) SPAWN.C ; SYMBOL.OBJ: SYMBOL.C DEF.H PROTOTYP.H CL $(CFLAGS) SYMBOL.C ; TEXT.OBJ: TEXT.C DEF.H PROTOTYP.H CL $(CFLAGS) TEXT.C ; TTY.OBJ: TTY.C DEF.H PROTOTYP.H CL $(CFLAGS) TTY.C ; TTYIO.OBJ: TTYIO.C DEF.H PROTOTYP.H CL $(CFLAGS) TTYIO.C ; TTYKBD.OBJ: TTYKBD.C DEF.H PROTOTYP.H CL $(CFLAGS) TTYKBD.C ; WANGPC.OBJ: WANGPC.C DEF.H PROTOTYP.H CL $(CFLAGS) WANGPC.C ; WINDOW.OBJ: WINDOW.C DEF.H PROTOTYP.H CL $(CFLAGS) WINDOW.C ; WORD.OBJ: WORD.C DEF.H PROTOTYP.H CL $(CFLAGS) WORD.C ; BEAV.EXE: BASIC.OBJ BUFFER.OBJ CINFO.OBJ DISPLAY.OBJ ECHO.OBJ EXTEND.OBJ \ EBCDIC.OBJ FILE.OBJ FILEIO.OBJ FORMAT.OBJ KBD.OBJ LINE.OBJ \ LANGUAGE.OBJ MAIN.OBJ RANDOM.OBJ TEXT.OBJ \ REGION.OBJ SEARCH.OBJ SPAWN.OBJ SYMBOL.OBJ TTY.OBJ TTYIO.OBJ \ TTYKBD.OBJ WINDOW.OBJ WORD.OBJ WANGPC.OBJ LINK @beav.lnk # LINK /MAP /CO @beav.lnk beav-140/makefile.os20000644000175000001440000000164405667134707014462 0ustar samusers00000000000000# Makefile for BEAV 1.40 # OS/2 port done by Kai Uwe Rommel # rommel@jonas.ucrc.sub.org default: @echo "Make target msc or gcc." # Microsoft C 6.00 (16-bit) msc: $(MAKE) -f makefile.os2 beav.exe \ CC="cl -nologo -AL -Oegit" O=".obj" CFLAGS="-W1 -Zep -J -G2s -UMSDOS" \ LDFLAGS="-Lp -Fb -F 4000 d:\msc\lib\setargv.obj -o" \ LIBS="-link /noe" DEF="beav.def" # emx gcc (32-bit) gcc: $(MAKE) -f makefile.os2 beav.exe \ CC="gcc -O -Zomf -Zsys" O=".obj" CFLAGS="" \ LDFLAGS="-s -o" LIBS="-los2" DEF="beav32.def" OBJ = basic$O buffer$O cinfo$O display$O ebcdic$O echo$O extend$O file$O \ fileio$O format$O kbd$O line$O main$O random$O region$O search$O \ spawn$O symbol$O tcap$O termcap$O termio$O text$O tty$O ttyio$O \ ttykbd$O wangpc$O window$O word$O DEFINES = -DUNIX -DOS2 .c$O: $(CC) $(CFLAGS) $(DEFINES) -c $< beav.exe: $(OBJ) $(DEF) $(CC) $(OBJ) $(DEF) $(LDFLAGS) $@ $(LIBS) (OBJ): def.h prototyp.h beav-140/makefile.rs60000644000175000001440000000125705667134707014471 0ustar samusers00000000000000# This is a makefile for IBM RS/6000 CFLAGS= -O -DUNIX -DNOPROTO OFILES= basic.o ebcdic.o fileio.o region.o text.o wangpc.o \ language.o buffer.o echo.o main.o search.o tty.o window.o \ cinfo.o extend.o kbd.o spawn.o ttyio.o termio.o tcap.o word.o \ display.o file.o line.o random.o symbol.o ttykbd.o format.o CFILES= basic.c ebcdic.c fileio.c region.c text.c wangpc.c \ buffer.c echo.c format.c main.c search.c tty.c window.c \ cinfo.c extend.c kbd.c spawn.c ttyio.c termio.c tcap.c word.c \ language.c display.c file.c line.c random.c symbol.c ttykbd.c HFILES= def.h beav: $(OFILES) $(CC) $(CFLAGS) $(OFILES) -lcurses -lc -o beav (OFILES): $(HFILES) beav-140/makefile.utx0000644000175000001440000000127405667134707014576 0ustar samusers00000000000000# This is the makefile for DEC ULTRIX CFLAGS= -O -DUNIX -DBSD -DULTRIX -DNOPROTO OFILES= basic.o ebcdic.o fileio.o region.o text.o wangpc.o \ language.o buffer.o echo.o main.o search.o tty.o window.o \ cinfo.o extend.o kbd.o spawn.o ttyio.o termio.o tcap.o word.o \ display.o file.o line.o random.o symbol.o ttykbd.o format.o CFILES= basic.c ebcdic.c fileio.c region.c text.c wangpc.c \ buffer.c echo.c format.c main.c search.c tty.c window.c \ cinfo.c extend.c kbd.c spawn.c ttyio.c termio.c tcap.c word.c \ language.c display.c file.c line.c random.c symbol.c ttykbd.c HFILES= def.h beav: $(OFILES) $(CC) $(CFLAGS) $(OFILES) -ltermcap -lc -o beav (OFILES): $(HFILES) beav-140/makefile.uxv0000644000175000001440000000125505667134707014577 0ustar samusers00000000000000# This is the makefile for System V UNIX CFLAGS= -O -DUNIX -DSYSV OFILES= basic.o ebcdic.o fileio.o region.o text.o wangpc.o \ language.o buffer.o echo.o main.o search.o tty.o window.o \ cinfo.o extend.o kbd.o spawn.o ttyio.o termio.o tcap.o word.o \ display.o file.o line.o random.o symbol.o ttykbd.o format.o CFILES= basic.c ebcdic.c fileio.c region.c text.c wangpc.c \ buffer.c echo.c format.c main.c search.c tty.c window.c \ cinfo.c extend.c kbd.c spawn.c ttyio.c termio.c tcap.c word.c \ language.c display.c file.c line.c random.c symbol.c ttykbd.c HFILES= def.h beav: $(OFILES) $(CC) $(CFLAGS) $(OFILES) -ltermcap -lc -o beav (OFILES): $(HFILES) beav-140/prototyp.h0000644000175000001440000002132705667134707014331 0ustar samusers00000000000000extern char backchar (int f, int n, int k); extern char forwchar (int f, int n, int k); extern char move_ptr (struct WINDOW *wp, long len, char dot, char fix, char rel); extern char wind_on_dot (struct WINDOW *wp); extern char gotobob (void); extern char gotoeob (void); extern char forwline (int f, int n, int k); extern char backline (int f, int n, int k); extern char forwpage (int f, int n, int k); extern char backpage (int f, int n, int k); extern char setmark (void); extern char swapmark (void); extern char gotoline (int f, int n, int k); extern char usebuffer (void); extern char use_buffer (void); extern char _usebuffer (char *bufn); extern char killbuffer (void); extern char _killbuffer (char *bufn); extern char listbuffers (void); extern char showsavebuf (void); extern char popblist (void); extern char makelist (void); extern char addline (char *text); extern char anycb (void); extern struct BUFFER *bfind (char *bname, int cflag); extern struct BUFFER *bcreate (char *bname); extern char bclear (struct BUFFER *bp); extern char next_buf (void); extern char prev_buf (void); extern char yank_buffer (void); extern char _yankbuffer (char *bufn); extern char buffername (void); extern char killablebufs (struct BUFFER *bp); extern char onebuf (struct BUFFER *bp); extern void funky_name (char *bname, int n); extern char pickone (void); extern char bufsizlock (void); extern void b_append_l (struct BUFFER *buf_p, struct LINE *lp); extern char b_append_c (struct BUFFER *buf_p, unsigned char ch); extern void save_buf_init (void); extern void save_buf_home (void); extern unsigned short get_save_char (void); extern void vtinit (void); extern void vtfree (void); extern void vttidy (void); extern void vtmove (int row, int col); extern void vtputc (char c); extern char vtputd (struct WINDOW *wp, int row); extern void bin_to_text (char *bin_buf, char *txt_buf, unsigned int len, struct ROW_FMT *fmt_ptr); extern unsigned short get_int (unsigned char *w_buf); extern unsigned long get_long (unsigned char *w_buf); extern double get_double (unsigned char *w_buf); extern unsigned int fill_buf (struct WINDOW *wp, struct LINE *lin, unsigned int lin_off, char *w_buff, unsigned int cnt); extern void vteeol (void); extern void update (void); extern unsigned int get_currow (struct WINDOW *wp); extern unsigned int get_curcol (struct WINDOW *wp); extern void mem_line (int row, struct vid *vvp); extern void ucopy (struct vid *vvp, struct vid *pvp); extern void uline (int row, struct vid *vvp, struct vid *pvp); extern void modeline (struct WINDOW *wp); extern void writ_echo (char *buf); extern char print (void); extern char to_ebcdic (char ch); extern void eerase (void); extern char eyesno (char *sp); extern char ereply (char *fp, char *buf, int nbuf, char *arg); extern char eread (char *fp, char *buf, int nbuf, int flag, char *ap); extern int getxtra (struct SYMBOL *sp1, struct SYMBOL *sp2, int cpos); extern void eformat (char *fp, char *ap); extern void eputi (int i, int r); extern void eputs (char *s); extern void eputc (int c); extern void err_echo (char *buf); extern char bindtokey (void); extern char extend (int f, int n, int k); extern char help (void); extern void sort_buf (struct BUFFER *b_ptr, int cnt); extern char wallchart (int f, int n, int k); extern void check_extend (char *sfname); extern char *flook (char *fname, int hflag); extern char load_extend (void); extern int find_keyval (char *name); extern char fileread (void); extern char fileinsert (void); extern char file_visit (int f, int n, int k); extern char viewfile (void); extern char filevisit (void); extern char load_file (char *fname, unsigned long start, unsigned long end); extern char readin (char *fname, unsigned long start, unsigned long end); extern void makename (char *bname, char *fname); extern char filewrite (void); extern char filesave (void); extern char writeout (char *fn, unsigned long start, unsigned long end, unsigned short mode); extern char filename (void); extern char parse_f_name (char *fn, unsigned long *start, unsigned long *end); extern char ffropen (char *fn); extern unsigned long file_len (void); extern char ffwopen (char *fn, int mode); extern char ffclose (void); extern char ffputline (char *buf, int nbuf); extern char ffgetline (char *buf, unsigned int nbuf, unsigned int *rbuf); extern unsigned long ffseek (unsigned long posn); extern char fbackupfile (char *fname); extern void adjustcase (char *fn); extern void init_fmt (void); extern int getkey (void); extern int getctl (void); extern void keyname (char *cp, int k); extern struct LINE *lalloc (int size); extern void lfree (struct LINE *lp); extern void lchange (int flag); extern struct LINE *l_break_in_two (struct LINE *lp, unsigned int lo, unsigned int extra); extern char linsert (int n, unsigned char c); extern char ldelete (unsigned long n_bytes, int kflag); extern void lreplace (int n, char c); extern char lrepl_str (int plen, struct LINE *rstr, struct LINE *mstr); extern void l_fix_up (struct LINE *line); extern void main (int argc, char **argv); extern char execute (int c, int f, int n); extern void edinit (char *bname); extern char flush_all (void); extern char flushnquit (int f, int n, int k); extern char quit (int f, int n, int k); extern char ctlxlp (int f, int n, int k); extern char ctlxrp (int f, int n, int k); extern char ctlxe (int f, int n, int k); extern char ctrlg (int f, int n, int k); extern char showversion (int f, int n, int k); extern void _lowercase (char *s); extern char autosave (void); extern char showcpos (int f, int n, int k); extern char twiddle (void); extern char quote (int f, int n, int k); extern char insert_toggle (void); extern char selfinsert (int f, int n, int k); extern char insertunit (int f, int n, int k); extern char fill_out (void); extern char dec_chr_ok (char *char_buf, char *max_str, char chr, char pos); extern void set_mode_vars (void); extern char asciimode (void); extern char ebcdicmode (void); extern char floatmode (void); extern char decimalmode (void); extern char hexmode (void); extern char octalmode (void); extern char binarymode (void); extern char dispshift (int f, int n, int k); extern char forwdel (int f, int n, int k); extern char backdel (int f, int n, int k); extern char dispsize1 (void); extern char dispsize2 (void); extern char dispsize4 (void); extern char dispswapbyte (int f, int n, int k); extern char yank (int f, int n, int k); extern char linkwind (void); extern void bad_key (int key); extern char n_way_combine (int f, int n, int k); extern char n_way_split (int f, int n, int k); extern void wind_on_dot_all (void); extern char killregion (int f, int n, int k); extern char copyregion (int f, int n, int k); extern char getregion (struct reg *rp); extern char save_region (int f, int n, int k); extern char forwsearch (void); extern char backsearch (void); extern char searchagain (void); extern char queryrepl (int f, int n, int k); extern char replaceit (void); extern char forwsrch (void); extern char backsrch (void); extern char readpattern (void); extern char recall (void); extern void next_pat (void); extern char compare (void); extern char spawncli (int f, int n, int k); extern struct SYMBOL *symlookup (char *cp); extern int symhash (char *cp); extern void keymapinit (void); extern void keyadd (short new, char (*funcp) (void), char *name, int modify); extern void keydup (int new, char *name); extern void ttinit (void); extern void tttidy (void); extern void ttmove (int row, int col); extern void tteeol (void); extern void tteeop (void); extern void ttbeep (void); extern void asciiparm (int n); extern void ttnowindow (void); extern void ttcolor (int color); extern void ttopen (void); extern void ttclose (void); extern void ttflush (void); extern int ttputc (int c); extern void putline (int row, int startcol, int stringsize, char *string); extern int ttkeyready (void); extern int ttgetc (void); extern void ttraw (void); extern void ttcooked (void); extern void set_crt_type (void); extern void ungetkey (int k); extern int getkbd (void); extern void ttykeymapinit (void); extern char *keystrings (int key); extern void is_wang (void); extern int getsysconfig (union REGS *outregs, struct SREGS *segregs); extern char getscreenstate (void); extern char reposition (void); extern char nextwind (void); extern char prevwind (void); extern char mvdnwind (int f, int n, int k); extern char mvupwind (int f, int n, int k); extern char onlywind (void); extern char delwind (void); extern char splitwind (void); extern char enlargewind (int f, int n, int k); extern char shrinkwind (int f, int n, int k); extern struct WINDOW *wpopup (void); extern char refresh (void); extern char screen_rows (int f, int n, int k); extern char backunit (int f, int n, int k); extern char forwunit (int f, int n, int k); extern char delfunit (int f, int n, int k); extern char delbunit (int f, int n, int k); beav-140/random.c0000644000175000001440000007561105667134707013711 0ustar samusers00000000000000/* * Assorted commands. * The file contains the command * processors for a large assortment of unrelated * commands. The only thing they have in common is * that they are all command processors. */ #include "def.h" char backdel (); bool fill_out (); void bad_key (); D64 get_double (); extern char MSG_sh_pos[]; extern char MSG_sh_pos1[]; extern char MSG_f_str[]; extern char MSG_3u[]; extern char MSG_5u[]; extern char MSG_lu[]; extern char MSG_03u[]; extern char MSG_05u[]; extern char MSG_010lu[]; extern char MSG_116e[]; extern char MSG_lnk[]; extern char MSG_unlink[]; extern char MSG_link[]; extern char MSG_bad_key[]; extern char MSG_esc[]; extern char MSG_ctl_x[]; extern char MSG_ctl[]; extern char MSG_key_code[]; extern char char_str[]; extern char MSG_w_not_empty[]; extern char MSG_procing[]; extern char MSG_ok[]; extern char MSG_edit_float[]; #if RUNCHK extern char ERR_rnd_1[]; extern char ERR_rnd_2[]; extern char ERR_rnd_3[]; extern char ERR_rnd_4[]; extern char ERR_rnd_5[]; extern char ERR_rnd_6[]; extern char ERR_rnd_7[]; #endif extern ROW_FMT ascii_fmt; extern ROW_FMT ebcdic_fmt; extern ROW_FMT binary_8_fmt; extern ROW_FMT binary_16_fmt; extern ROW_FMT binary_32_fmt; extern ROW_FMT octal_8_fmt; extern ROW_FMT octal_16_fmt; extern ROW_FMT octal_32_fmt; extern ROW_FMT decimal_8_fmt; extern ROW_FMT decimal_16_fmt; extern ROW_FMT decimal_32_fmt; #if FLOAT_DISP extern ROW_FMT float_64_fmt; #endif extern ROW_FMT hex_8_fmt; extern ROW_FMT hex_16_fmt; extern ROW_FMT hex_32_fmt; extern bool read_pat_mode; extern bool dont_repeat; extern BUFFER sav_buf; char dec_chr_ok (); ulong get_long (); void wind_on_dot_all (); /* * Display a bunch of useful information about * the current location of dot and mark. * The position of the dot and mark and the difference between them. * The total buffer size is displayed. * This is normally bound to "C-X =". */ bool showcpos (f, n, k) int f, n, k; { A32 dotoff, markoff, fsize, bsize; char buf[NCOL * 2], buf1[NCOL * 2]; dotoff = curwp->w_dotp->l_file_offset; dotoff += curwp->w_doto; if (curwp->w_markp != NULL) { markoff = curwp->w_markp->l_file_offset; markoff += curwp->w_marko; } bsize = curwp->w_bufp->b_linep->l_bp->l_file_offset; bsize += curwp->w_bufp->b_linep->l_bp->l_used; fsize = curbp->b_file_size; if (curwp->w_markp != NULL) { /* build format string */ sprintf (buf1, MSG_sh_pos, R_POS_FMT (curwp), R_POS_FMT (curwp), R_POS_FMT (curwp), R_POS_FMT (curwp)); sprintf (buf, buf1, dotoff, markoff, bsize, fsize); } else { /* build format string */ sprintf (buf1, MSG_sh_pos1, R_POS_FMT (curwp), R_POS_FMT (curwp), R_POS_FMT (curwp)); sprintf (buf, buf1, dotoff, bsize, fsize); } sprintf (&buf[strlen (buf)], MSG_f_str, curbp->b_fname); writ_echo (buf); return (TRUE); } /* * Twiddle the two characters on either side of * dot. If dot is at the end of the line twiddle the * two characters before it. Return with an error if dot * is at the beginning of line; it seems to be a bit * pointless to make this work. This fixes up a very * common typo with a single stroke. Normally bound * to "C-T". This always works within a line, so * "WFEDIT" is good enough. */ bool twiddle () { register LINE *dotp; register short doto; char b_per_u, f_buf[4], s_buf[4], i; dotp = curwp->w_dotp; doto = curwp->w_doto; b_per_u = curwp->w_fmt_ptr->r_b_per_u; /* try to move back one unit */ if (!move_ptr (curwp, (long) -b_per_u, TRUE, TRUE, TRUE)) { curwp->w_dotp = dotp; /* if fail then restore dot and quit */ curwp->w_doto = doto; ttbeep (); return (FALSE); } /* pick up first unit byte by byte */ for (i = 0; i < b_per_u; i++) { f_buf[i] = DOT_CHAR (curwp); move_ptr (curwp, 1L, TRUE, FALSE, TRUE); } /* move to the end of the second unit */ if (!move_ptr (curwp, (long) (b_per_u - 1), TRUE, FALSE, TRUE)) { curwp->w_dotp = dotp; /* if fail then restore dot and quit */ curwp->w_doto = doto; ttbeep (); return (FALSE); } /* pick up second unit (reverse order) and deposit second unit */ for (i = 0; i < b_per_u; i++) { s_buf[i] = DOT_CHAR (curwp); DOT_CHAR (curwp) = f_buf[b_per_u - 1 - i]; move_ptr (curwp, -1L, TRUE, FALSE, TRUE); } /* deposit first unit */ for (i = 0; i < b_per_u; i++) { DOT_CHAR (curwp) = s_buf[i]; move_ptr (curwp, -1L, TRUE, FALSE, TRUE); } curwp->w_dotp = dotp; curwp->w_doto = doto; lchange (WFHARD); return (TRUE); } /* * Quote the next character, and insert it into the buffer. * All the characters are taken literally. * The character is always read, even if it is inserted 0 times, for * regularity. */ bool quote (f, n, k) int f, n, k; { register int c; if (kbdmop != NULL) c = *kbdmop++; else { c = ttgetc (); if (kbdmip != NULL) { if (kbdmip > &kbdm[NKBDM - 4]) { ctrlg (FALSE, 0, KRANDOM); return (ABORT); } *kbdmip++ = c; } } if (n < 0) return (FALSE); if (n == 0) return (TRUE); return (linsert (n, (uchar) c)); } /* * Toggle the insert mode. Insert mode is used only in ASCII or EBCDIC modes. */ bool insert_toggle () /* toggle routine for selfinsert */ { register WINDOW *wp; if (curbp->b_flag & BFSLOCK) return (TRUE); if (read_pat_mode) dont_repeat = TRUE; insert_mode = !insert_mode; for (wp = wheadp; wp; wp = wp->w_wndp) wp->w_flag |= WFMODE; /* force mode line update */ return (TRUE); } /* * Ordinary text characters are bound to this function, * which inserts them into the buffer. Characters marked as control * characters (using the CTRL flag) may be remapped to their ASCII * equivalent. This makes TAB (C-I) work right, and also makes the * world look reasonable if a control character is bound to this * this routine by hand. Any META or CTLX flags on the character * are discarded. * * Edit the unit under the cursor. * Check that the character is valid for the current display mode. */ bool selfinsert (f, n, k) int f, n, k; { register int c; char edt_buf[8], i_chr, b_per_u, u_offs, u_roffs, bit_shf, i; LINE *l_ptr; short d_offs; int bytes, temp_int; long dot_shf, l_mask, l_val; D64 d_val; char text_buf[32]; static char max_dec_8[] = "255"; static char max_dec_16[] = "65535"; static char max_dec_32[] = "4294967295"; int cur_col; bool intel; if (n < 0) { ttbeep (); return (FALSE); } if (n == 0) { ttbeep (); return (TRUE); } c = k & KCHAR; if ((k & KCTRL) != 0 && c >= '@' && c <= '_') /* ASCII-ify. */ c -= '@'; b_per_u = curwp->w_fmt_ptr->r_b_per_u; u_offs = curwp->w_unit_offset; u_roffs = curwp->w_fmt_ptr->r_chr_per_u - u_offs - 1; intel = curwp->w_intel_mode; cur_col = ttcol; switch ((uchar) (curwp->w_fmt_ptr->r_type)) { case EBCDIC: c = to_ebcdic ((uchar) c); /* convert ASCII to EBCDIC */ case ASCII: if ((insert_mode) || (DOT_POS (curwp) == BUF_SIZE (curwp))) linsert (n, (uchar) c); else lreplace (n, (uchar) c); break; case HEX: if ((c >= '0') && (c <= '9')) { i_chr = c - '0'; /* convert to binary */ } else if ((c >= 'A') && (c <= 'F')) { i_chr = c - 'A' + 10; /* convert to binary */ } else if ((c >= 'a') && (c <= 'f')) { i_chr = c - 'a' + 10; /* convert to binary */ } else { bad_key (k); return (FALSE); } fill_out (); /* expand buffer if necessary */ /* position dot to byte to be altered */ if (intel) dot_shf = u_roffs >> 1; else dot_shf = u_offs >> 1; /* save dot position for later */ l_ptr = curwp->w_dotp; d_offs = curwp->w_doto; move_ptr (curwp, dot_shf, TRUE, FALSE, TRUE); if (u_offs & 1) { /* lower nibble in byte */ i_chr &= 0x0f; DOT_CHAR (curwp) &= 0xf0; DOT_CHAR (curwp) |= i_chr; } else { /* upper nibble in byte */ i_chr <<= 4; i_chr &= 0xf0; DOT_CHAR (curwp) &= 0x0f; DOT_CHAR (curwp) |= i_chr; } /* restore dot position */ curwp->w_dotp = l_ptr; curwp->w_doto = d_offs; forwchar (0, 1, KRANDOM); /* advance the cursor */ break; case BINARY: if ((c != '0') && (c != '1')) { bad_key (k); return (FALSE); } /* position dot to byte to be altered */ if (intel) dot_shf = u_roffs >> 3; else dot_shf = u_offs >> 3; fill_out (); /* expand buffer if necessary */ /* save dot position for later */ l_ptr = curwp->w_dotp; d_offs = curwp->w_doto; move_ptr (curwp, dot_shf, TRUE, FALSE, TRUE); bit_shf = u_roffs & 0x07; if (c == '0') { DOT_CHAR (curwp) &= ~(1 << bit_shf); } else { DOT_CHAR (curwp) |= 1 << bit_shf; } /* restore dot position */ curwp->w_dotp = l_ptr; curwp->w_doto = d_offs; forwchar (0, 1, KRANDOM); /* advance the cursor */ break; case OCTAL: if (c < '0') { bad_key (k); return (FALSE); } else if ((c > '1') && (u_offs == 0) && ((curwp->w_fmt_ptr->r_size) == WORDS)) { bad_key (k); return (FALSE); } else if ((c > '3') && (u_offs == 0)) { bad_key (k); return (FALSE); } else if (c > '7') { bad_key (k); return (FALSE); } dot_shf = (c - '0') & 7;/* get binary value */ l_mask = 7; /* create bit mask */ dot_shf <<= (u_roffs * 3); l_mask <<= (u_roffs * 3); fill_out (); /* expand buffer if necessary */ /* save dot position for later */ l_ptr = curwp->w_dotp; d_offs = curwp->w_doto; /* position dot to the byte to be altered */ if (intel) { for (i = 0; i < b_per_u; i++) { DOT_CHAR (curwp) &= ~((D8) l_mask & 0xff); DOT_CHAR (curwp) |= (D8) dot_shf & 0xff; l_mask >>= 8; dot_shf >>= 8; move_ptr (curwp, 1L, TRUE, FALSE, TRUE); } } else { move_ptr (curwp, (long) (b_per_u - 1), TRUE, FALSE, TRUE); /* move to last byte */ for (i = 0; i < b_per_u; i++) { DOT_CHAR (curwp) &= ~((D8) l_mask & 0xff); DOT_CHAR (curwp) |= (D8) dot_shf & 0xff; l_mask >>= 8; dot_shf >>= 8; move_ptr (curwp, -1L, TRUE, FALSE, TRUE); /* step back one byte */ } } /* restore dot position */ curwp->w_dotp = l_ptr; curwp->w_doto = d_offs; forwchar (0, 1, KRANDOM); /* advance the cursor */ break; case DECIMAL: fill_out (); /* expand buffer if necessary */ /* save dot position for later */ l_ptr = curwp->w_dotp; d_offs = curwp->w_doto; bytes = fill_buf (curwp, l_ptr, d_offs, edt_buf, b_per_u); /* if last unit is not full and must be extended */ for (; bytes < b_per_u; bytes++) { edt_buf[3] = edt_buf[2]; /* shuffle bytes down */ edt_buf[2] = edt_buf[1]; edt_buf[1] = edt_buf[0]; edt_buf[0] = 0; } switch (curwp->w_fmt_ptr->r_size) { case BYTES: sprintf (text_buf, MSG_03u, (int) (edt_buf[0] & 0xff)); if (!dec_chr_ok (text_buf, max_dec_8, (char) c, u_offs)) { bad_key (k); return (TRUE); /* TRUE so that mask will be same len */ } sscanf (text_buf, MSG_3u, &i); /* convert back to binary */ l_val = (long) i & 0xff; break; case WORDS: l_val = get_int (edt_buf); /* do intel swap */ sprintf (text_buf, MSG_05u, (int) (l_val & 0xFFFF)); if (!dec_chr_ok (text_buf, max_dec_16, (char) c, u_offs)) { bad_key (k); return (TRUE); /* TRUE so that mask will be same len */ } sscanf (text_buf, MSG_5u, &temp_int); /* convert back to binary */ l_val = get_int ((char *) &temp_int); /* do intel swap */ break; case DWORDS: l_val = get_long (edt_buf); /* do intel swap */ sprintf (text_buf, MSG_010lu, l_val); if (!dec_chr_ok (text_buf, max_dec_32, (char) c, u_offs)) { bad_key (k); return (TRUE); /* TRUE so that mask will be same len */ } sscanf (text_buf, MSG_lu, &l_val); /* convert back to binary */ l_val = get_long ((char *) &l_val); /* do intel swap */ break; #if RUNCHK default: writ_echo (ERR_rnd_2); break; #endif } DOT_CHAR (curwp) = (char) l_val & 0xff; for (i = 1; i < b_per_u; i++) { l_val >>= 8; move_ptr (curwp, 1L, TRUE, FALSE, TRUE); /* step forward one byte */ DOT_CHAR (curwp) = (char) l_val & 0xff; } /* restore dot position */ curwp->w_dotp = l_ptr; curwp->w_doto = d_offs; forwchar (0, 1, KRANDOM); /* advance the cursor */ break; case FLOAT: { char temp_text[32]; D64 d_temp; /* couldn't make this work so error it out */ writ_echo (MSG_edit_float); return (FALSE); fill_out (); /* expand buffer if necessary */ /* save dot position for later */ l_ptr = curwp->w_dotp; d_offs = curwp->w_doto; bytes = fill_buf (curwp, l_ptr, d_offs, edt_buf, b_per_u); /* if last unit is not full and must be extended */ for (; bytes < b_per_u; bytes++) { edt_buf[7] = edt_buf[6]; /* shuffle bytes down */ edt_buf[6] = edt_buf[5]; edt_buf[5] = edt_buf[4]; edt_buf[4] = edt_buf[3]; edt_buf[3] = edt_buf[2]; edt_buf[2] = edt_buf[1]; edt_buf[1] = edt_buf[0]; edt_buf[0] = 0; } d_val = get_double (edt_buf); /* do intel swap */ /* get a text representation of the float */ sprintf (text_buf, MSG_116e, d_val); /* insert the character that was typed */ text_buf[u_offs] = c; /* see if scanf get get back a good number */ /************************************************ This is where the problem lies. The sscanf would not read in the same number that the sprinf would spit out. Maybe the sscanf did not like the scientific notation at maximum precesion. pvr 7/4/94 *************************************************/ if (sscanf (text_buf, MSG_116e, &d_temp) != 1) { bad_key (k); return (TRUE); /* TRUE so that mask will be same len */ } /* printf the the number */ sprintf (temp_text, MSG_116e, d_temp); /* see if the text strings match */ if (strcmp (temp_text, text_buf)) { bad_key (k); return (TRUE); /* TRUE so that mask will be same len */ } sscanf (text_buf, MSG_116e, &d_val); /* convert back to binary */ d_val = get_double ((char *) &d_val); /* do intel swap */ DOT_CHAR (curwp) = (char) d_val & 0xff; for (i = 1; i < b_per_u; i++) { D8 *ptr; ptr = (D8 *) & d_val; move_ptr (curwp, 1L, TRUE, FALSE, TRUE); /* step forward one byte */ DOT_CHAR (curwp) = ptr[i] & 0xff; } /* restore dot position */ curwp->w_dotp = l_ptr; curwp->w_doto = d_offs; forwchar (0, 1, KRANDOM); /* advance the cursor */ break; } #if RUNCHK default: writ_echo (ERR_rnd_3); break; #endif } /* if cursor has wrapped to the next line then previous line will not be refreshed with WFEDIT so do a WFHARD */ if (cur_col > get_curcol (curwp)) lchange (WFHARD); else lchange (WFEDIT); return (TRUE); } /* * Insert one unit of zeros at the current dot position. */ bool insertunit (f, n, k) int f, n, k; { lchange (WFEDIT); linsert ((R_B_PER_U (curwp) * n), 0); return (TRUE); } /* * Increase the size of the buffer if necessary. * If dot is at the byte after the last full unit * then add enough bytes to the buffer to create * a full unit at the end. */ bool fill_out () { long buf_size, dot_pos, last_unit; int b_per_u; char stat, shift; int insert_val; buf_size = BUF_SIZE (curwp); dot_pos = DOT_POS (curwp); b_per_u = R_B_PER_U (curwp); shift = curwp->w_disp_shift; stat = TRUE; insert_val = 0; last_unit = buf_size & ~((long) (b_per_u - 1)); /* there is an even number of units step back one */ if (last_unit == buf_size) last_unit -= b_per_u; last_unit += shift; /* if dot is one byte past the end of the buffer */ if (dot_pos > last_unit) { insert_val = b_per_u; } /* if dot is pointed at the end of the buffer */ else if (dot_pos == last_unit) { insert_val = b_per_u - (buf_size - last_unit); } /* if insert is necessary then do it */ if (insert_val != 0) { lchange (WFHARD); move_ptr (curwp, buf_size, TRUE, FALSE, FALSE); /* move dot to end */ stat = linsert (insert_val, 0); move_ptr (curwp, dot_pos, TRUE, TRUE, FALSE); /* put dot back */ } return (stat); } /* * This checks that an entered character is ok * for the position given. */ char dec_chr_ok (char_buf, max_str, chr, pos) char chr, pos, *char_buf, *max_str; { char i; if ((chr < '0') || (chr > '9')) return (FALSE); char_buf[pos] = chr; /* insert typed char */ /* check if number is too big */ for (i = 0; max_str[i] != 0; i++) { if (char_buf[i] < max_str[i]) break; /* if char is smaller then must be ok */ if (char_buf[i] > max_str[i]) return (FALSE); /* val is too large; ERROR */ } return (TRUE); } /* * Set the rest of the variables for the mode change. */ void set_mode_vars () { curwp->w_disp_shift = 0; /* shift to 0 when changing mode */ curwp->w_unit_offset = 0; /* go to end of unit */ /* if we are in the middle of a search then use the proper format struc */ if (read_pat_mode) curwp->w_fmt_ptr = curwp->w_fmt_ptr->r_srch_fmt; wind_on_dot (curwp); curwp->w_flag = WFHARD; update (); } /* * Change the display mode to ASCII. * The default binding is META C-A. */ bool asciimode () { curwp->w_fmt_ptr = &ascii_fmt; set_mode_vars (); return (TRUE); } /* * Change the display mode to EBCDIC. * The default binding is META C-E. */ bool ebcdicmode () { curwp->w_fmt_ptr = &ebcdic_fmt; set_mode_vars (); return (TRUE); } #if FLOAT_DISP /* * Change the display mode to FLOAT. * The default binding is META C-F. */ bool floatmode () { curwp->w_fmt_ptr = &float_64_fmt; set_mode_vars (); return (TRUE); } #endif /* * Change the display mode to DECIMAL. * The default binding is META C-D. */ bool decimalmode () { switch (curwp->w_fmt_ptr->r_size) { case BYTES: curwp->w_fmt_ptr = &decimal_8_fmt; break; case WORDS: curwp->w_fmt_ptr = &decimal_16_fmt; break; case DOUBLES: case DWORDS: curwp->w_fmt_ptr = &decimal_32_fmt; break; #if RUNCHK default: writ_echo (ERR_rnd_4); break; #endif } set_mode_vars (); return (TRUE); } /* * Change the display mode to HEXADECIMAL. * The default binding is META C-H. */ bool hexmode () { switch (curwp->w_fmt_ptr->r_size) { case BYTES: curwp->w_fmt_ptr = &hex_8_fmt; break; case WORDS: curwp->w_fmt_ptr = &hex_16_fmt; break; case DWORDS: case DOUBLES: curwp->w_fmt_ptr = &hex_32_fmt; break; #if RUNCHK default: writ_echo (ERR_rnd_5); break; #endif } set_mode_vars (); return (TRUE); } /* * Change the display mode to OCTAL. * The default binding is META C-O. */ bool octalmode () { switch (curwp->w_fmt_ptr->r_size) { case BYTES: curwp->w_fmt_ptr = &octal_8_fmt; break; case WORDS: curwp->w_fmt_ptr = &octal_16_fmt; break; case DOUBLES: case DWORDS: curwp->w_fmt_ptr = &octal_32_fmt; break; #if RUNCHK default: writ_echo (ERR_rnd_6); break; #endif } set_mode_vars (); return (TRUE); } /* * Change the display mode to BINARY. * The default binding is META C-B. */ bool binarymode () { switch (curwp->w_fmt_ptr->r_size) { case BYTES: curwp->w_fmt_ptr = &binary_8_fmt; break; case WORDS: curwp->w_fmt_ptr = &binary_16_fmt; break; case DOUBLES: case DWORDS: curwp->w_fmt_ptr = &binary_32_fmt; break; #if RUNCHK default: writ_echo (ERR_rnd_7); break; #endif } set_mode_vars (); return (TRUE); } /* * Change the display shift. * Circularly rotate through display shift of 0 through 3. * This value is used to shift the display by the designated number of bytes. * This is used to cause WORD and DWORD values to be calculated * from the correct offset. */ bool dispshift (f, n, k) int f, n, k; { uchar mode, size; if (read_pat_mode) return (TRUE); /* no shift is allowed in search mode */ mode = curwp->w_fmt_ptr->r_type; size = curwp->w_fmt_ptr->r_size; if (((mode == HEX) || (mode == FLOAT) || (mode == DECIMAL) || (mode == BINARY) || (mode == OCTAL)) && (size != BYTES)) { if ((size == WORDS) && (curwp->w_disp_shift >= 1)) { /* roll over on words */ curwp->w_disp_shift = 0; } else { if ((size == DWORDS) && (curwp->w_disp_shift >= 3)) { /* roll over on longs */ curwp->w_disp_shift = 0; } else { if ((size == DOUBLES) && (curwp->w_disp_shift >= 7)) { /* roll over on doubles */ curwp->w_disp_shift = 0; } else { curwp->w_disp_shift++; /* increment shift */ } } } } else { curwp->w_disp_shift = 0;/* set to no shift */ } move_ptr (curwp, 0L, TRUE, TRUE, TRUE); wind_on_dot (curwp); curwp->w_flag = WFHARD; /* force full window refresh */ return (TRUE); } /* * Delete forward. This is real * easy, because the basic delete routine does * all of the work. Watches for negative arguments, * and does the right thing. If any argument is * present, it kills rather than deletes, to prevent * loss of text if typed with a big argument. * Normally bound to "C-D". */ char forwdel (f, n, k) int f, n, k; { char s; if (n < 0) return (backdel (f, -n, KRANDOM)); s = FALSE; if (R_SIZE (curwp) == BYTES) { if (f != FALSE) { /* Really a kill. */ if ((lastflag & CFKILL) == 0) bclear (&sav_buf); thisflag |= CFKILL; } s = ldelete ((A32) n, f); curwp->w_unit_offset = 0; } return (s); } /* * Delete backwards. This is quite easy too, * because it's all done with other functions. Just * move the cursor back, and delete forwards. * Like delete forward, this actually does a kill * if presented with an argument. */ char backdel (f, n, k) int f, n, k; { int u_off; char s; if (n < 0) return (forwdel (f, -n, KRANDOM)); s = FALSE; if (R_SIZE (curwp) == BYTES) { u_off = curwp->w_unit_offset; curwp->w_unit_offset = 0; if ((s = backchar (f, n * R_CHR_PER_U (curwp), KRANDOM)) == TRUE) { s = ldelete ((A32) n, f); if (f != FALSE) { /* Really a kill. */ if ((lastflag & CFKILL) == 0) bclear (&sav_buf); thisflag |= CFKILL; } } curwp->w_unit_offset = u_off; } return (s); } /* * Change the size of the display unit to BYTE. * Adjust byte shift to the allowable range. * Normally bound to "META-1". */ bool dispsize1 () { curwp->w_disp_shift = 0; /* shift to 0 when changing size */ curwp->w_unit_offset = 0; /* go to end of unit */ switch ((uchar) (R_TYPE (curwp))) { case OCTAL: curwp->w_fmt_ptr = &octal_8_fmt; break; case DECIMAL: curwp->w_fmt_ptr = &decimal_8_fmt; break; case HEX: curwp->w_fmt_ptr = &hex_8_fmt; break; case BINARY: curwp->w_fmt_ptr = &binary_8_fmt; break; default: return (TRUE); break; } /* if we are in the middle of a search then use the proper format struc */ if (read_pat_mode) curwp->w_fmt_ptr = curwp->w_fmt_ptr->r_srch_fmt; move_ptr (curwp, 0L, TRUE, TRUE, TRUE); wind_on_dot (curwp); curwp->w_flag = WFHARD; update (); return (TRUE); } /* * Change the size of the display unit to WORD. * Adjust byte shift to the allowable range. * Normally bound to "META-2". */ bool dispsize2 () { curwp->w_disp_shift = 0; /* shift to 0 when changing size */ curwp->w_unit_offset = 0; /* go to end of unit */ switch ((uchar) (R_TYPE (curwp))) { case OCTAL: curwp->w_fmt_ptr = &octal_16_fmt; break; case DECIMAL: curwp->w_fmt_ptr = &decimal_16_fmt; break; case HEX: curwp->w_fmt_ptr = &hex_16_fmt; break; case BINARY: curwp->w_fmt_ptr = &binary_16_fmt; break; default: return (TRUE); break; } /* if we are in the middle of a search then use the proper format struc */ if (read_pat_mode) curwp->w_fmt_ptr = curwp->w_fmt_ptr->r_srch_fmt; move_ptr (curwp, 0L, TRUE, TRUE, TRUE); wind_on_dot (curwp); curwp->w_flag = WFHARD; update (); return (TRUE); } /* * Change the size of the display unit to long. * Adjust byte shift to the allowable range. * Normally bound to "META-4". */ bool dispsize4 () { curwp->w_disp_shift = 0; /* shift to 0 when changing size */ curwp->w_unit_offset = 0; /* go to end of unit */ switch ((uchar) (R_TYPE (curwp))) { case OCTAL: curwp->w_fmt_ptr = &octal_32_fmt; break; case DECIMAL: curwp->w_fmt_ptr = &decimal_32_fmt; break; case HEX: curwp->w_fmt_ptr = &hex_32_fmt; break; case BINARY: curwp->w_fmt_ptr = &binary_32_fmt; break; default: return (TRUE); break; } /* if we are in the middle of a search then use the proper format struc */ if (read_pat_mode) curwp->w_fmt_ptr = curwp->w_fmt_ptr->r_srch_fmt; move_ptr (curwp, 0L, TRUE, TRUE, TRUE); wind_on_dot (curwp); curwp->w_flag = WFHARD; update (); return (TRUE); } /* * Display byte swaped. This command causes the bytes * that are displayed in WORD and DWORD mode to be swaped * in the way that the INTEL microprocessors do it. */ bool dispswapbyte (f, n, k) int f, n, k; { if ((curwp->w_fmt_ptr->r_size) == BYTES) return (TRUE); if (curwp->w_intel_mode) curwp->w_intel_mode = FALSE; else curwp->w_intel_mode = TRUE; curwp->w_flag = WFHARD; update (); return (TRUE); } /* * Yank text back from the kill buffer. This * is really easy. All of the work is done by the * standard insert routines. All you do is run the loop, * and check for errors. * An attempt has been made to fix the cosmetic bug * associated with a yank when dot is on the top line of * the window (nothing moves, because all of the new * text landed off screen). */ bool yank (f, n, k) int f, n, k; { register D16 c; register A32 i; char buf[NCOL], buf1[NCOL]; if (n < 0) return (FALSE); while (n--) { i = 0; save_buf_home (); while ((c = get_save_char ()) != (D16) - 1) { if (linsert (1, (uchar) c) == FALSE) return (FALSE); if ((i & 0x2ff) == 0) { sprintf (buf1, MSG_procing, R_POS_FMT (curwp)); sprintf (buf, buf1, (ulong) i); writ_echo (buf); /* check if we should quit */ if (ttkeyready ()) { wind_on_dot_all (); if (ttgetc () == CTL_G) return (FALSE); } } ++i; } } /* update buffer display */ if ((blistp->b_nwnd != 0) && (blistp->b_type == BTLIST)) listbuffers (); curwp->w_flag |= WFHARD; return (TRUE); } /* * Link windows. pvr * This function toggles the window linking function. * When linking is enabled all windows that look at * the same buffer will be forced to have the same * dot position. Each window is then moved to be * positioned on the dot. Thus when a user moves * arround a buffer all other views into that buffer * will follow. */ bool linkwind () { char buf[NCOL]; if (curwp->w_bufp->b_flag & BFLINK) { curwp->w_bufp->b_flag &= ~(BFLINK & 0xff); sprintf (buf, MSG_lnk, curwp->w_bufp->b_bname, MSG_unlink); } else { curwp->w_bufp->b_flag |= BFLINK; sprintf (buf, MSG_lnk, curwp->w_bufp->b_bname, MSG_link); } writ_echo (buf); return (TRUE); } /* * Print all bad keys to the screen and beep */ void bad_key (key) int key; { char buf[NCOL]; ttbeep (); sprintf (buf, MSG_bad_key); keyname (&buf[strlen (buf)], key); sprintf (&buf[strlen (buf)], ", %X", key); writ_echo (buf); } /* * Combine sequential bytes from the rest of the windows * into this window. This is useful in combining PROM * image files from odd and even bytes into one file. */ bool n_way_combine (f, n, k) int f, n, k; { WINDOW *dest_wp, *src_wp; BUFFER *src_bp; A32 dotp; D8 byt; int j = 0; char buf[NCOL], buf1[NCOL]; /* save the destination window for later restore */ dest_wp = curwp; if ((BUF_SIZE (curwp)) != (A32) 0) { writ_echo (MSG_w_not_empty); return (FALSE); } /* Current window must be empty, modifiable and not the only one. */ if ((BUF_SIZE (curwp) != 0) || (curwp->w_wndp == NULL) || (curwp->w_bufp->b_flag & (BFVIEW | BFSLOCK))) { writ_echo (MSG_w_not_empty); return (FALSE); } for (;;) { /* step to the next window after the destination window */ nextwind (); /* as I cycle around the windows skip the destination window */ if (curwp == dest_wp) { continue; } byt = DOT_CHAR (curwp) & 0xff; dotp = DOT_POS (curwp); /* get the current dot position */ /* move the dot position ahead in current buffer */ if (move_ptr (curwp, 1L, TRUE, FALSE, TRUE) == FALSE) { /* did we advance? */ if (DOT_POS (curwp) == dotp) { wind_on_dot_all (); writ_echo (MSG_ok); return (TRUE); /* done all that we could */ } } src_wp = curwp; src_bp = curwp->w_bufp; curwp = dest_wp; curbp = dest_wp->w_bufp; if (linsert (1, byt) == FALSE) { wind_on_dot_all (); return (FALSE); /* insert failed for some reason */ } curwp = src_wp; curbp = src_bp; if ((j++ & 0x2ff) == 0) { sprintf (buf1, MSG_procing, R_POS_FMT (curwp)); sprintf (buf, buf1, dotp); writ_echo (buf); /* check if we should quit */ if (ttkeyready ()) { wind_on_dot_all (); if (ttgetc () == CTL_G) return (FALSE); } } } } /* * Split the current buffer into the rest of the windows. * This is useful in splitting a binary file into PROM * image files. */ bool n_way_split (f, n, k) int f, n, k; { WINDOW *src_wp; A32 b_size; D8 byt; int j = 0; char buf[NCOL], buf1[NCOL]; /* save the source window and buffer for later restore */ src_wp = curwp; /* step to the next window after the source window */ nextwind (); /* check that all the destination windows are empty and modifiable */ for (;;) { if ((BUF_SIZE (curwp) != 0) || (curwp->w_bufp->b_flag & (BFVIEW | BFSLOCK))) { writ_echo (MSG_w_not_empty); return (FALSE); } /* force all windows to be refreshed */ lchange (WFHARD); /* step to the next window */ nextwind (); /* stop after one pass around the windows */ if (curwp == src_wp) break; } b_size = BUF_SIZE (src_wp); /* get the buffer size */ /* do the split until source is exhausted */ for (;;) { /* step to the next window after the source window */ nextwind (); /* current window cannot be the source */ if (curwp == src_wp) continue; byt = DOT_CHAR (src_wp) & 0xff; /* get the byte to copy */ /* are we at the end of the buffer */ if (b_size == DOT_POS (src_wp)) { wind_on_dot_all (); writ_echo (MSG_ok); return (TRUE); } if (linsert (1, byt) == FALSE) { wind_on_dot_all (); return (FALSE); } if ((j++ & 0x2ff) == 0) { sprintf (buf1, MSG_procing, R_POS_FMT (src_wp)); sprintf (buf, buf1, DOT_POS (src_wp)); writ_echo (buf); /* check if we should quit */ if (ttkeyready ()) { wind_on_dot_all (); if (ttgetc () == CTL_G) return (FALSE); } } if (move_ptr (src_wp, 1L, TRUE, FALSE, TRUE) == FALSE) { wind_on_dot_all (); writ_echo (MSG_ok); return (TRUE); /* hit the end of the source buffer */ } } } void wind_on_dot_all () { WINDOW *wp; wp = curwp; do { wind_on_dot (curwp); nextwind (); } while (wp != curwp); } beav-140/read.me0000644000175000001440000000574605667134707013525 0ustar samusers00000000000000 BEAV (Binary Editor And Viewer), is 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 edit multiple files in multiple windows and cut and paste between them. 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. 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 the following systems; UNIX SYS5 makefile.uxv UNIX BSD makefile.bsd LINUX makefile.uxv 386BSD makefile.bsd XENIX 286 makefile.286 AmigaDOS makefile.amg Microsoft C 5.1 makefile.mc5 Microsoft C 7.0 makefile.mc7 DEC ULTRIX makefile.utx OS/2 makefile.os2 AIX makefile.rs6 Select the appropriate one and rename it to makefile. Run make. BEAV has been run on the following machines; 8088, 8086, 286 and 386 PC's RS6000 MIPS HP Precision Architecture SUN AMIGA DEC The old Wang PC BEAV has international language support. All language dependent text strings are in a seperate file. The English language text file is called english.c. The language that is desired should have it's ".c" file copied to language.c. This is the file that will be complied and linked. This initial release of the international language support contains only an english.c file. The language.c file supplied is a copy of the english.c file. BEAV is available various archives, on WSMR-SIMTEL20.ARMY.MIL it is; PD1:BEAV140.ZIP MSDOS executable and doc PD1:BEAV140S.ZIP source and doc Version 1.40 (3/31/93) of BEAV contains the following enhancements; * Support for different languages. All English text strings are contained in a seperate file. I would like to get translations to other languages. I will then include them in future releases. Key codes are 8 bit values now. This allows extended character sets. * A bug has been fixed in the search command. If the backspace key was hit while entering the search string, some error messages were displayed. * Another bug has been fixed in the search command. While entering a search pattern if you went back and inserted characters in the search pattern the cursor would advance one position too far. * BEAV will compile under OS/2. There is a makefile called makefile.os2. The OS/2 support is thanks to Kai Uwe Rommel (rommel@jonas.gold.sub.org) I am willing to maintain BEAV and will entertain suggestions for modifications and/or bug fixes. I can be reached at; pvr@wiis.wang.com or at; Peter Reilley 19 Heritage Cir. Hudson, N.H. 03051 beav-140/readme.amg0000644000175000001440000000135605667134707014203 0ustar samusers00000000000000BEAV 1.32 - Binary Editor And Viewer by Peter Reilley (pvr@wang.com), AMIGA port by Simon J Raybould (sie@fulcrum.bt.co.uk) Installation ------------ beav will read a file called "beavrc" from the current directory, or S: if it can't find one in the current directory, to map keys to your preference. Be aware though that if you re-map a key sequence that is generated by a function key, the new command will be invoked by that function key as it is translated to the same sequence. Any Amiga specific problems to sie@fulcrum.bt.co.uk Any other probs to the original author in the doc file. Thanks ------ Many thanks to Kim DeVaughn for testing the amiga port of BEAV and suggesting changes that have improved the port, thanks Kim! beav-140/region.c0000644000175000001440000001060105667134707013700 0ustar samusers00000000000000/* * Region based commands. * The routines in this file * deal with the region, that magic space * between "." and mark. Some functions are * commands. Some functions are just for * internal use. */ #include "def.h" bool getregion (); extern char MSG_sv_in_b[]; extern char MSG_sav_slf[]; extern char MSG_no_mark[]; extern char MSG_procing[]; extern BUFFER sav_buf; /* * Kill the region. Ask "getregion" * to figure out the bounds of the region. * Move "." to the start, and kill the characters. */ char killregion (f, n, k) int f, n, k; { register char s; REGION region; int error; if ((s = getregion (®ion)) != TRUE) return (s); if ((lastflag & CFKILL) == 0) /* This is a kill type */ bclear (&sav_buf); thisflag |= CFKILL; /* kill buffer stuff. */ curwp->w_dotp = region.r_linep; curwp->w_doto = region.r_offset; error = ldelete (region.r_size, TRUE); lchange (WFHARD); /* cause the save buffer display to be updated if needed */ if (sav_buf.b_nwnd != 0) showsavebuf (); writ_echo (okmsg); return (error); } /* * Copy all of the characters in the * region to the kill buffer. Don't move dot * at all. This is a bit like a kill region followed * by a yank. */ char copyregion (f, n, k) int f, n, k; { register LINE *linep; register int loffs, j; register char s; REGION region; char buf[NCOL], buf1[NCOL]; j = 0; if ((s = getregion (®ion)) != TRUE) return (s); if ((lastflag & CFKILL) == 0) /* Kill type command. */ bclear (&sav_buf); thisflag |= CFKILL; linep = region.r_linep; /* Current line. */ loffs = region.r_offset; /* Current offset. */ while (region.r_size--) { if ((s = b_append_c (&sav_buf, (uchar) lgetc (linep, loffs))) != TRUE) return (s); ++loffs; /* step to next line */ if (linep->l_used <= loffs) { linep = linep->l_fp; loffs = 0; } if ((j++ & 0x2ff) == 0) { sprintf (buf1, MSG_procing, R_POS_FMT (curwp)); sprintf (buf, buf1, DOT_POS (curwp)); writ_echo (buf); /* check if we should quit */ if (ttkeyready ()) { wind_on_dot_all (); if (ttgetc () == '*') return (FALSE); } } } /* cause the save buffer display to be updated if needed */ if (sav_buf.b_nwnd != 0) showsavebuf (); /* update buffer display */ if ((blistp->b_nwnd != 0) && (blistp->b_type == BTLIST)) listbuffers (); writ_echo (okmsg); return (TRUE); } /* * This routine figures out the bound of the region * in the current window, and stores the results into the fields * of the REGION structure. Dot and mark are usually close together, * but I don't know the order. The size is kept in a long. At the * end, after the size is figured out, it is assigned to the size * field of the region structure. If this assignment loses any bits, * then we print an error. This is "type independent" overflow * checking. All of the callers of this routine should be ready to * get an ABORT status, because I might add a "if regions is big, * ask before clobberring" flag. */ bool getregion (rp) register REGION *rp; { if (curwp->w_markp == NULL) { writ_echo (MSG_no_mark); return (FALSE); } if (DOT_POS (curwp) < MARK_POS (curwp)) { rp->r_linep = curwp->w_dotp; rp->r_offset = curwp->w_doto; rp->r_size = MARK_POS (curwp) - DOT_POS (curwp); } else { rp->r_linep = curwp->w_markp; rp->r_offset = curwp->w_marko; rp->r_size = DOT_POS (curwp) - MARK_POS (curwp); } return (TRUE); } /* save some region in a buffer * (use _usebuffer to handle non-existent buffers) * * hack as it uses kill buffer to transfer stuff (quick and dirty!) * and doesn't do clever things at all with dot in destination buffer! */ char save_region (f, n, k) int f, n, k; { char bufn[NBUFN]; char oldbufn[NBUFN]; register char s; if ((s = ereply (MSG_sv_in_b, bufn, NBUFN, NULL)) != TRUE) return (s); if (strcmp (bufn, curbp->b_bname) == 0) { writ_echo (MSG_sav_slf); return (FALSE); } /* save this name for ughly reversal */ strcpy (oldbufn, curbp->b_bname); /* copy stuff using killbuffer as work space - hack !! * than move it to named place using yank - Quick AND Dirty */ copyregion (f, n, k); _usebuffer (bufn); curbp->b_type = BTSAVE; /* mark as a saved buffer */ yank (f, n, k); _usebuffer (oldbufn); writ_echo (okmsg); return (TRUE); } beav-140/search.c0000644000175000001440000005773705667134707013707 0ustar samusers00000000000000/* * Search commands. * The functions in this file implement the * search commands (both plain and incremental searches * are supported) and the query-replace command. */ #include "def.h" char replaceit (); char forwsrch (); char backsrch (); char readpattern (); void next_pat (); extern char MSG_sch_str[]; extern char MSG_bsrc_str[]; extern char MSG_rpl_str[]; extern char MSG_pat_fnd[]; extern char MSG_no_srch[]; extern char MSG_fnd_at[]; extern char MSG_no_rpl[]; extern char MSG_1_rpl[]; extern char MSG_n_rpl[]; extern char MSG_srcing[]; extern char MSG_curs[]; extern char MSG_cmp_end[]; extern char MSG_cmp_term[]; extern char MSG_cmp_dif[]; extern char MSG_only_2[]; extern char MSG_cmping[]; extern char MSG_not_fnd[]; #if RUNCHK extern char ERR_rdpat[]; extern char ERR_mask[]; extern char ERR_m_cl[]; #endif #define CCHR(x) ((x)-'@') #define SRCH_BEGIN (0) /* Search sub-codes. */ #define SRCH_FORW (-1) #define SRCH_BACK (-2) #define SRCH_PREV (-3) #define SRCH_NEXT (-4) #define SRCH_NOPR (-5) #define SRCH_ACCM (-6) typedef struct { int s_code; LINE *s_dotp; short s_doto; } SRCHCOM; #define MAX_PAT 260 extern ROW_FMT hex_s_8_fmt; extern ROW_FMT ascii_s_fmt; bool recall_flag = FALSE; bool read_pat_mode = FALSE; bool srch_mode = FALSE; bool rplc_mode = FALSE; bool dont_repeat = FALSE; /* used to prevent toggling commands from */ /* failing in read_pattern */ static char srch_patb[MAX_PAT]; static char srch_maskb[MAX_PAT]; static char rplc_patb[MAX_PAT]; static char rplc_maskb[MAX_PAT]; static LINE *srch_pat = (LINE *) srch_patb; static LINE *srch_mask = (LINE *) srch_maskb; static LINE *cur_pat; static LINE *cur_mask; static LINE *rplc_pat = (LINE *) rplc_patb; static LINE *rplc_mask = (LINE *) rplc_maskb; static int old_srch_pat_size = 0; /* for pattern recall */ static int old_rplc_pat_size = 0; static ROW_FMT *old_fmt = &hex_s_8_fmt; char *cur_prompt; int srch_lastdir = SRCH_NOPR; /* Last search flags. */ /* * Search forward. * Get a search string from the user, and search for it, * starting at ".". If found, "." gets moved to the * first matched character, and display does all the hard stuff. * If not found, it just prints a message. */ char forwsearch () { register char s; char buf[NCOL], buf1[NCOL]; srch_mode = TRUE; rplc_mode = FALSE; cur_prompt = MSG_sch_str; if ((s = readpattern ()) != TRUE) { srch_mode = FALSE; eerase (); /* clear message line */ return (s); } if (forwsrch () == FALSE) { writ_echo (MSG_not_fnd); srch_mode = FALSE; return (FALSE); } srch_lastdir = SRCH_FORW; curwp->w_flag |= WFMODE; /* update mode line */ curwp->w_unit_offset = 0; /* build format */ sprintf (buf1, MSG_pat_fnd, R_POS_FMT (curwp)); sprintf (buf, buf1, curwp->w_dotp->l_file_offset + curwp->w_doto); writ_echo (buf); srch_mode = FALSE; return (TRUE); } /* * Reverse search. * Get a search string from the user, and search, starting at "." * and proceeding toward the front of the buffer. If found "." is left * pointing at the first character of the pattern [the last character that * was matched]. */ char backsearch () { register char s; char buf[NCOL], buf1[NCOL]; srch_mode = TRUE; rplc_mode = FALSE; cur_prompt = MSG_bsrc_str; if ((s = readpattern ()) != TRUE) { srch_mode = FALSE; eerase (); /* clear message line */ return (s); } if (backsrch () == FALSE) { writ_echo (MSG_not_fnd); srch_mode = FALSE; return (FALSE); } srch_lastdir = SRCH_BACK; curwp->w_flag |= WFMODE; /* update mode line */ curwp->w_unit_offset = 0; sprintf (buf1, MSG_pat_fnd, R_POS_FMT (curwp)); sprintf (buf, buf1, curwp->w_dotp->l_file_offset + curwp->w_doto); writ_echo (buf); srch_mode = FALSE; return (TRUE); } /* * Search again, using the same search string * and direction as the last search command. The direction * has been saved in "srch_lastdir", so you know which way * to go. */ char searchagain () { char buf[NCOL], buf1[NCOL]; long dot_pos; srch_mode = TRUE; rplc_mode = FALSE; dot_pos = DOT_POS (curwp); if (srch_lastdir == SRCH_FORW) { /* advance one unit so we don't find the same thing again */ move_ptr (curwp, dot_pos + 1, TRUE, FALSE, FALSE); if (forwsrch () == FALSE) { /* go back to orig pt */ move_ptr (curwp, dot_pos, TRUE, FALSE, FALSE); writ_echo (MSG_not_fnd); srch_mode = FALSE; return (FALSE); } curwp->w_flag |= WFMODE;/* update mode line */ curwp->w_unit_offset = 0; sprintf (buf1, MSG_pat_fnd, R_POS_FMT (curwp)); sprintf (buf, buf1, curwp->w_dotp->l_file_offset + curwp->w_doto); writ_echo (buf); srch_mode = FALSE; return (TRUE); } if (srch_lastdir == SRCH_BACK) { /* step back one unit so we don't find the same thing again */ move_ptr (curwp, dot_pos - 1, TRUE, FALSE, FALSE); if (backsrch () == FALSE) { /* go back to orig pt */ move_ptr (curwp, dot_pos, TRUE, FALSE, FALSE); writ_echo (MSG_not_fnd); srch_mode = FALSE; return (FALSE); } curwp->w_flag |= WFMODE;/* update mode line */ curwp->w_unit_offset = 0; sprintf (buf1, MSG_pat_fnd, R_POS_FMT (curwp)); sprintf (buf, buf1, curwp->w_dotp->l_file_offset + curwp->w_doto); writ_echo (buf); srch_mode = FALSE; return (TRUE); } writ_echo (MSG_no_srch); srch_mode = FALSE; return (FALSE); } /* * Query Replace. * Replace strings selectively. Does a search and replace operation. * A space or a comma replaces the string, a period replaces and quits, * an n doesn't replace, a C-G quits. * (note typical hack to add a function with minimal code) */ char queryrepl (f, n, k) int f, n, k; { register char s; srch_mode = FALSE; rplc_mode = TRUE; cur_prompt = MSG_sch_str; if (s = readpattern ()) { replaceit (); } srch_mode = FALSE; rplc_mode = FALSE; return (s); } char replaceit () { int rcnt = 0; /* Replacements made so far */ int plen; /* length of found string */ int rlen; /* length of replace string */ long abs_dot_p; /* absolute dot position */ long abs_mark_p; /* absolute mark position */ char buf[NCOL], buf1[NCOL]; /* * Search forward repeatedly, checking each time whether to insert * or not. The "!" case makes the check always true, so it gets put * into a tighter loop for efficiency. * * If we change the line that is the remembered value of dot, then * it is possible for the remembered value to move. This causes great * pain when trying to return to the non-existant line. * * possible fixes: * 1) put a single, relocated marker in the WINDOW structure, handled * like mark. The problem now becomes a what if two are needed... * 2) link markers into a list that gets updated (auto structures for * the nodes) * 3) Expand the mark into a stack of marks and add pushmark, popmark. */ plen = srch_pat->l_used; rlen = rplc_pat->l_used; abs_dot_p = DOT_POS (curwp);/* save current dot position */ if (curwp->w_markp != NULL) /* mark may not be set */ abs_mark_p = MARK_POS (curwp); while (forwsrch () == TRUE) { retry: sprintf (buf1, MSG_fnd_at, R_POS_FMT (curwp)); sprintf (buf, buf1, DOT_POS (curwp)); writ_echo (buf); curwp->w_flag |= WFMODE;/* update mode line */ update (); switch (ttgetc ()) { case 'r': case 'R': case ' ': case ',': /* update has fixedup the dot position so move to found byte */ /* go and do the replace */ if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE) return (FALSE); /* begin searching after replace string */ move_ptr (curwp, (long) rlen, TRUE, FALSE, TRUE); rcnt++; break; case 'o': case 'O': case '.': if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE) return (FALSE); /* begin searching after replace string */ move_ptr (curwp, (long) rlen, TRUE, FALSE, TRUE); rcnt++; goto stopsearch; case 'q': case 'Q': case CCHR ('G'): ctrlg (FALSE, 0, KRANDOM); goto stopsearch; case 'a': case 'A': case '!': do { if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE) return (FALSE); /* begin searching after replace string */ move_ptr (curwp, (long) rlen, TRUE, FALSE, TRUE); rcnt++; } while (forwsrch () == TRUE); goto stopsearch; case 's': case 'S': case 'n': /* begin searching after this byte */ move_ptr (curwp, 1L, TRUE, FALSE, TRUE); break; default: ttbeep (); goto retry; } } stopsearch: move_ptr (curwp, abs_dot_p, TRUE, TRUE, FALSE); if (curwp->w_markp != NULL) { swapmark (); /* insure that the mark points to the same byte as before */ if (abs_mark_p > abs_dot_p) move_ptr (curwp, abs_mark_p + rlen - plen, TRUE, FALSE, FALSE); else move_ptr (curwp, abs_mark_p, TRUE, FALSE, FALSE); swapmark (); } curwp->w_flag |= WFHARD; update (); if (rcnt == 0) { writ_echo (MSG_no_rpl); } else if (rcnt == 1) { writ_echo (MSG_1_rpl); } else { sprintf (buf1, MSG_n_rpl, R_POS_FMT (curwp)); sprintf (buf, buf1, (ulong) rcnt); writ_echo (buf); } flush_count += rcnt; /* jam for auto write buffers */ return (TRUE); } /* * This routine does the real work of a * forward search. The pattern is sitting in the external * variable "srch_pat" the mask if in "srch_mask". * If found, dot is updated, the window system * is notified of the change, and TRUE is returned. If the * string isn't found, FALSE is returned. */ char forwsrch () { register LINE *save_dotp, *save2_dotp; register int save_doto, save2_doto; register D8 *pat_ptr, *mask_ptr; register int i, j, pat_cnt; register D8 first_pat, first_mask; char buf[NCOL], buf1[NCOL]; save_dotp = curwp->w_dotp; /* save dot position for later */ save_doto = curwp->w_doto; pat_ptr = srch_pat->l_text; mask_ptr = srch_mask->l_text; pat_cnt = srch_pat->l_used; first_mask = mask_ptr[0]; first_pat = pat_ptr[0] | first_mask; j = (int) DOT_POS (curwp) & 0xffff; do { if ((j++ & 0x2ff) == 0) { sprintf (buf1, MSG_srcing, R_POS_FMT (curwp)); sprintf (buf, buf1, DOT_POS (curwp)); writ_echo (buf); /* check if we should quit */ if (ttkeyready ()) { if (ttgetc () == CTL_G) break; } } if (first_pat == ((DOT_CHAR (curwp) | first_mask) & 0xff)) { save2_dotp = curwp->w_dotp; /* save dot position for later */ save2_doto = curwp->w_doto; for (i = 1; i < pat_cnt; i++) { if (!move_ptr (curwp, 1L, TRUE, FALSE, TRUE) || ((pat_ptr[i] & ~mask_ptr[i]) != (DOT_CHAR (curwp) & ~mask_ptr[i]))) { /* not found */ curwp->w_dotp = save2_dotp; /* restore dot position */ curwp->w_doto = save2_doto; break; } } if (i == pat_cnt) /* found */ { /* move back to the first matching unit */ move_ptr (curwp, -(long) pat_cnt + 1, TRUE, FALSE, TRUE); wind_on_dot (curwp); return (TRUE); } } } while (move_ptr (curwp, 1L, TRUE, FALSE, TRUE)); curwp->w_dotp = save_dotp; /* restore dot position */ curwp->w_doto = save_doto; return (FALSE); } /* * This routine does the real work of a * backward search. The pattern is sitting in the external * variable "srch_pat". If found, dot is updated, the window system * is notified of the change, and TRUE is returned. If the * string isn't found, FALSE is returned. */ char backsrch () { register LINE *save_dotp, *save_p; register LPOS save_doto, save_o; register D8 *pat_ptr, *mask_ptr; register int i, j, pat_cnt; register char first_pat, first_mask; char buf[NCOL], buf1[NCOL]; save_dotp = curwp->w_dotp; /* save dot position for later */ save_doto = curwp->w_doto; pat_ptr = srch_pat->l_text; mask_ptr = srch_mask->l_text; pat_cnt = srch_pat->l_used; first_mask = mask_ptr[0]; first_pat = pat_ptr[0] | first_mask; j = (int) DOT_POS (curwp) & 0xffff; do { /* check if we should quit */ if (ttkeyready ()) { if (ttgetc () == CTL_G) break; } if ((j-- & 0x2ff) == 0) { sprintf (buf1, MSG_srcing, R_POS_FMT (curwp)); sprintf (buf, buf1, DOT_POS (curwp)); writ_echo (buf); } if (first_pat == (curwp->w_dotp->l_text[curwp->w_doto] | first_mask)) { save_p = curwp->w_dotp; save_o = curwp->w_doto; for (i = 1; i < pat_cnt; i++) { if (!move_ptr (curwp, 1L, TRUE, FALSE, TRUE) || ((pat_ptr[i] & ~mask_ptr[i]) != (DOT_CHAR (curwp) & ~mask_ptr[i]))) { /* not found */ curwp->w_dotp = save_p; /* restore ptr to continue */ curwp->w_doto = save_o; break; } } if (i == pat_cnt) /* found */ { /* move back to the first matching unit */ move_ptr (curwp, -(long) pat_cnt + 1, TRUE, FALSE, TRUE); wind_on_dot (curwp); return (TRUE); } } } while (move_ptr (curwp, -1L, TRUE, FALSE, TRUE)); curwp->w_dotp = save_dotp; /* restore dot position */ curwp->w_doto = save_doto; return (FALSE); } /* * Read a pattern. * Display and edit in the form of the current window. * Slide the displayed line back and forth when the cursor hits a boundary. * Manage the mask buffer. When a '*' (wild card) is entered mask all * bits in that unit and display all '?'s. */ char readpattern () { int cod, mask_cod, curs_pos, curs_pos1, prt_siz, i, doto, loff; WINDOW srch_wind, *save_wind; BUFFER srch_buf, *save_buf; LINE head_line; int r_type, siz_prompt2, u_off; bool first_time, stat; char disp_buf[180], mask_buf[180], buf1[NCOL]; save_wind = curwp; /* save current window for later */ save_buf = curbp; /* save current buffer for later */ curwp = &srch_wind; /* search window is current window during search */ curbp = &srch_buf; cur_pat = srch_pat; /* set global variables for LINE finctions */ cur_mask = srch_mask; recall_flag = FALSE; first_time = TRUE; read_pat_mode = TRUE; curwp->w_wndp = NULL; curwp->w_bufp = curbp; curwp->w_linep = cur_pat; curwp->w_loff = 0; curwp->w_dotp = cur_pat; curwp->w_doto = 0; curwp->w_unit_offset = 0; curwp->w_toprow = 24; curwp->w_ntrows = 1; curwp->w_intel_mode = save_wind->w_intel_mode; curwp->w_disp_shift = 0; if (R_TYPE (save_wind) == TEXT) curwp->w_fmt_ptr = &ascii_s_fmt; else curwp->w_fmt_ptr = save_wind->w_fmt_ptr->r_srch_fmt; srch_buf.b_bufp = NULL; srch_buf.b_linep = &head_line; srch_buf.b_unit_offset = 0; /* unit offset pvr */ srch_buf.b_markp = NULL; srch_buf.b_marko = 0; srch_buf.b_flag = 0; srch_buf.b_nwnd = 1; srch_buf.b_fname[0] = 0; srch_buf.b_bname[0] = 0; head_line.l_fp = cur_pat; head_line.l_bp = cur_pat; head_line.l_file_offset = 0;/* pvr */ head_line.l_used = 0; head_line.l_size = 0; cur_pat->l_fp = &head_line; cur_pat->l_bp = &head_line; cur_pat->l_size = 266; /* leave some extra past 256 */ cur_pat->l_used = 0; cur_pat->l_file_offset = 0; cur_mask->l_fp = &head_line; cur_mask->l_bp = &head_line; cur_mask->l_size = 266; /* leave some extra past 256 */ cur_mask->l_used = 0; cur_mask->l_file_offset = 0; rplc_pat->l_fp = &head_line; rplc_pat->l_bp = &head_line; rplc_pat->l_size = 266; /* leave some extra past 256 */ rplc_pat->l_used = 0; rplc_pat->l_file_offset = 0; rplc_mask->l_fp = &head_line; rplc_mask->l_bp = &head_line; rplc_mask->l_size = 266; /* leave some extra past 256 */ rplc_mask->l_used = 0; rplc_mask->l_file_offset = 0; sprintf (buf1, MSG_curs, cur_prompt, R_BYTE_FMT (curwp), R_BYTE_FMT (curwp), R_BYTE_FMT (curwp)); sprintf (disp_buf, buf1, curwp->w_doto, curwp->w_fmt_ptr->r_chr_per_u - curwp->w_unit_offset - 1, curwp->w_dotp->l_used); siz_prompt2 = strlen (disp_buf); /* save prompt length for later */ for (i = siz_prompt2; i < NCOL; i++) /* clear rest of buffer */ disp_buf[i] = ' '; writ_echo (disp_buf); r_type = R_TYPE (curwp); while (TRUE) { /* position cursor */ curs_pos = curwp->w_doto - curwp->w_loff; if (curwp->w_fmt_ptr->r_size == 1) { curs_pos = curs_pos >> 1; } else if (curwp->w_fmt_ptr->r_size == 3) { curs_pos = curs_pos >> 2; } curs_pos1 = curwp->w_fmt_ptr->r_positions[curs_pos] + curwp->w_unit_offset + siz_prompt2; ttmove (nrow - 1, curs_pos1); ttflush (); cod = getkey (); if (cod == 0x014D || cod == 0x014A) /* check for return or linefeed */ { if ((rplc_mode == TRUE) && (cur_prompt == MSG_sch_str)) { next_pat (); dont_repeat = FALSE; /* fix up */ goto next_loop; } else { old_srch_pat_size = srch_pat->l_used; /* save for restore */ if (rplc_mode == TRUE) old_rplc_pat_size = rplc_pat->l_used; old_fmt = curwp->w_fmt_ptr; curwp = save_wind; /* restore current window */ curbp = save_buf; /* restore current buffer */ read_pat_mode = FALSE; return (TRUE); } } if ((cod >= ' ') && (cod < 0x7f)) { if ((r_type == ASCII) || (r_type == EBCDIC)) { mask_cod = '9'; /* use 9 as dummy char that will get through */ } else if ((r_type == DECIMAL) || (r_type == FLOAT)) { mask_cod = '0'; /* clear mask byte */ } else if (cod == '?') { cod = '0'; switch (r_type) { case OCTAL: if (curwp->w_unit_offset == 0) /* if first char */ { if (R_SIZE (curwp) == WORDS) mask_cod = '1'; else mask_cod = '3'; } else mask_cod = '7'; break; case HEX: mask_cod = 'F'; break; case BINARY: mask_cod = '1'; break; #if RUNCHK default: printf (ERR_rdpat); break; #endif } } else { mask_cod = '0'; } } else mask_cod = cod; /* must be control; do the same to the mask */ /* save current dot and window positions */ doto = curwp->w_doto; u_off = curwp->w_unit_offset; loff = curwp->w_loff; stat = execute (cod, FALSE, 1); if (stat == ABORT) { old_srch_pat_size = srch_pat->l_used; /* save for restore */ if (rplc_mode == TRUE) old_rplc_pat_size = rplc_pat->l_used; old_fmt = curwp->w_fmt_ptr; curwp = save_wind; /* restore current window */ curbp = save_buf; /* restore current buffer */ read_pat_mode = FALSE; return (FALSE); } /* If key is recall then reset the size variables */ if (first_time) { first_time = FALSE; if (recall_flag) { srch_pat->l_used = old_srch_pat_size; srch_mask->l_used = old_srch_pat_size; rplc_pat->l_used = old_rplc_pat_size; rplc_mask->l_used = old_rplc_pat_size; curwp->w_fmt_ptr = old_fmt; recall_flag = FALSE; } } /* if it was a toggling command, don't do it again */ if (!dont_repeat && (stat == TRUE)) { head_line.l_fp = cur_mask; /* point to mask */ head_line.l_bp = cur_mask; curwp->w_linep = cur_mask; curwp->w_dotp = cur_mask; curwp->w_loff = loff; curwp->w_doto = doto; curwp->w_unit_offset = u_off; execute (mask_cod, FALSE, 1); head_line.l_fp = cur_pat; /* restore pointers */ head_line.l_bp = cur_pat; curwp->w_linep = cur_pat; curwp->w_dotp = cur_pat; } else dont_repeat = FALSE; /* limit at 256 bytes */ if (cur_pat->l_used >= 256) { cur_mask->l_used = 255; cur_pat->l_used = 255; if (curwp->w_doto >= 256) { move_ptr (curwp, 255L, TRUE, TRUE, FALSE); /* last position */ } } /* if buffer is size locked then replace pattern must be the */ /* same size as the search pattern */ if (rplc_mode && (save_buf->b_flag & BFSLOCK)) { rplc_pat->l_used = srch_pat->l_used; rplc_mask->l_used = srch_pat->l_used; } r_type = R_TYPE (curwp); #if RUNCHK /* check that the pattern and the mask are the same size */ if (cur_pat->l_used != cur_mask->l_used) { printf (ERR_mask, cur_pat->l_used, cur_mask->l_used); } /* check that in ascii mode the byte that will be set to zero */ /* is the dummy char 9 */ /* if (((r_type == ASCII) && (cur_mask -> l_text[curwp -> w_doto - 1] != '9')) || ((r_type == EBCDIC) && (cur_mask -> l_text[curwp -> w_doto - 1] != to_ebcdic('9')))) printf (ERR_m_cl); */ #endif if (((r_type == ASCII) || (r_type == EBCDIC)) && ((cod >= ' ') && (cod < 0x7f))) cur_mask->l_text[doto] = 0; /* clear mask byte */ next_loop: sprintf (buf1, MSG_curs, cur_prompt, R_BYTE_FMT (curwp), R_BYTE_FMT (curwp), R_BYTE_FMT (curwp)); sprintf (disp_buf, buf1, curwp->w_doto, curwp->w_fmt_ptr->r_chr_per_u - curwp->w_unit_offset - 1, curwp->w_dotp->l_used); siz_prompt2 = strlen (disp_buf); /* save prompt length for later */ for (i = siz_prompt2; i < NCOL; i++) { disp_buf[i] = ' '; mask_buf[i] = ' '; } if ((curbp->b_flag & BFSLOCK) && (rplc_pat->l_used != srch_pat->l_used)) { rplc_pat->l_used = srch_pat->l_used; /* if dot is past the end then move it back, replace string only */ if (DOT_POS (curwp) > srch_pat->l_used) move_ptr (curwp, (long) srch_pat->l_used, TRUE, TRUE, FALSE); } wind_on_dot (curwp); /* figure number of bytes to convert to text */ if ((cur_pat->l_used - curwp->w_loff) < (prt_siz = curwp->w_fmt_ptr->r_bytes)) prt_siz = cur_pat->l_used - curwp->w_loff; bin_to_text (&cur_pat->l_text[curwp->w_loff], &disp_buf[siz_prompt2], prt_siz, curwp->w_fmt_ptr); /* change any char to a ? if any bit is set in the mask buffer */ if ((r_type != ASCII) && (r_type != EBCDIC)) { /* print the contents of the mask to a invisible buffer */ bin_to_text (&cur_mask->l_text[curwp->w_loff], &mask_buf[siz_prompt2], prt_siz, curwp->w_fmt_ptr); for (i = siz_prompt2; (disp_buf[i] != 0) && (i < NCOL); i++) { if ((mask_buf[i] != '0') && (mask_buf[i] != ' ')) disp_buf[i] = '?'; } } else { for (i = 0; i < prt_siz; i++) { if (cur_mask->l_text[curwp->w_loff + i] != 0) disp_buf[i + siz_prompt2] = '?'; } } writ_echo (disp_buf); } } /* * Recall the last contents of the search string */ bool recall () { recall_flag = TRUE; return (TRUE); } /* * Switch between search pattern and replace pattern and their * respective masks */ void next_pat () { if (cur_pat == srch_pat) { cur_prompt = MSG_rpl_str; cur_pat = rplc_pat; /* point to replace pattern */ cur_mask = rplc_mask; } else { cur_prompt = MSG_sch_str; cur_pat = srch_pat; /* point to search pattern */ cur_mask = srch_mask; } curwp->w_dotp = cur_pat; curwp->w_linep = cur_pat; curbp->b_linep->l_fp = cur_pat; curbp->b_linep->l_bp = cur_pat; if (curwp->w_doto > cur_pat->l_used) { curwp->w_doto = cur_pat->l_used; curwp->w_unit_offset = 0; } if (curwp->w_loff > cur_pat->l_used) curwp->w_loff = cur_pat->l_used; dont_repeat = TRUE; } /* * Compare the contents of two windows. * There must be exactly two windows displayed. * The bytes under the cursor in each window are compared and if * a difference is found then the loop is stopped with the dot * position in each window pointing to the difference. * The two windows can be pointing at the same or different buffers. */ bool compare () { WINDOW *wp1, *wp2; bool move1, move2; int j; char *term_str = MSG_cmp_dif; char buf[NCOL], buf1[NCOL]; if (wheadp->w_wndp->w_wndp != NULL) { writ_echo (MSG_only_2); return (FALSE); } wp1 = wheadp; wp2 = wheadp->w_wndp; j = (int) DOT_POS (curwp) & 0xffff; wp1->w_flag |= WFMOVE; wp2->w_flag |= WFMOVE; while (DOT_CHAR (wp1) == DOT_CHAR (wp2)) { if ((j++ & 0xff) == 0) { sprintf (buf1, MSG_cmping, R_POS_FMT (curwp)); sprintf (buf, buf1, DOT_POS (curwp)); writ_echo (buf); /* check if we should quit */ if (ttkeyready ()) { if (ttgetc () == CTL_G) { term_str = MSG_cmp_term; break; } } } move1 = move_ptr (wp1, 1L, TRUE, FALSE, TRUE); move2 = move_ptr (wp2, 1L, TRUE, FALSE, TRUE); if (!(move1 && move2)) { term_str = MSG_cmp_end; break; } } writ_echo (term_str); wind_on_dot (wp1); wind_on_dot (wp2); return (TRUE); } beav-140/spawn.c0000644000175000001440000000272605667134707013556 0ustar samusers00000000000000/* * MS-DOS spawn command.com */ #include "def.h" #ifdef OS2 #define MSDOS 1 #endif extern char MSG_shell[]; extern char MSG_def_shell[]; extern char MSG_pmpt[]; extern char MSG_pt[]; extern char MSG_pme[]; extern char MSG_null[]; /* #include */ #ifdef MSDOS #include "process.h" #endif char *cspec = NULL; /* Command string. */ char *pspec = NULL; /* * Create a subjob with a copy * of the command intrepreter in it. When the * command interpreter exits, mark the screen as * garbage so that you do a full repaint. */ bool spawncli (f, n, k) int f, n, k; { #ifdef MSDOS char *getenv (); char old_prompt[NCOL]; char prompt_line[NCOL]; ttcolor (CTEXT); /* Normal color. */ ttmove (nrow - 1, 0); /* Last line. */ ttflush (); ttcooked (); #ifndef OS2 #ifndef IBM strcpy (prompt_line, MSG_pmpt); pspec = getenv (MSG_pt); strcpy (old_prompt, pspec); strcat (prompt_line, pspec); if (strlen (prompt_line - strlen (MSG_pme)) >= 64) /* VERY rude, but setenv not found */ { if (putenv (MSG_pmpt) == -1) exit (1); } else if (putenv (prompt_line) == -1) exit (1); #endif #endif if (!cspec && !(cspec = getenv (MSG_shell))) /* jam */ cspec = MSG_def_shell; spawnl (P_WAIT, cspec, MSG_null, NULL); #ifndef OS2 #ifndef IBM putenv (MSG_pme); if (putenv (old_prompt) == -1) exit (1); #endif #endif ttraw (); sgarbf = TRUE; #endif return (TRUE); } beav-140/symbol.c0000644000175000001440000004262705667134707013737 0ustar samusers00000000000000/* * Symbol table stuff. * Symbol tables, and keymap setup. * The terminal specific parts of building the * keymap has been moved to a better place. */ #include "def.h" void keyadd (); void keydup (); extern char MSG_byte_shift[]; extern char MSG_back_char[]; extern char MSG_quit[]; extern char MSG_forw_del_char[]; extern char MSG_toggle_swap[]; extern char MSG_forw_char[]; extern char MSG_abort[]; extern char MSG_ins_self[]; extern char MSG_back_del_char[]; extern char MSG_refresh[]; extern char MSG_forw_line[]; extern char MSG_back_line[]; extern char MSG_quote[]; extern char MSG_recall[]; extern char MSG_twiddle[]; extern char MSG_forw_page[]; extern char MSG_kill_region[]; extern char MSG_yank[]; extern char MSG_down_window[]; extern char MSG_ins_toggle[]; extern char MSG_display_buffers[]; extern char MSG_quit[]; extern char MSG_exit_flush_all[]; extern char MSG_set_file_name[]; extern char MSG_file_insert[]; extern char MSG_buf_size_lock[]; extern char MSG_flush_all[]; extern char MSG_down_window[]; extern char MSG_up_window[]; extern char MSG_file_read[]; extern char MSG_file_save[]; extern char MSG_file_visit[]; extern char MSG_file_write[]; extern char MSG_swap_dot_and_mark[]; extern char MSG_shrink_window[]; extern char MSG_display_position[]; extern char MSG_start_macro[]; extern char MSG_end_macro[]; extern char MSG_help[]; extern char MSG_only_window[]; extern char MSG_del_window[]; extern char MSG_split_window[]; extern char MSG_use_buffer[]; extern char MSG_spawn_cli[]; extern char MSG_execute_macro[]; extern char MSG_goto_line[]; extern char MSG_ins_unit[]; extern char MSG_kill_buffer[]; extern char MSG_load_bindings[]; extern char MSG_forw_window[]; extern char MSG_back_window[]; extern char MSG_view_file[]; extern char MSG_enlarge_window[]; extern char MSG_ascii_mode[]; extern char MSG_binary_mode[]; extern char MSG_buffer_name[]; extern char MSG_decimal_mode[]; extern char MSG_ebcdic_mode[]; #if FLOAT_DISP extern char MSG_float_mode[]; #endif extern char MSG_hex_mode[]; extern char MSG_back_del_unit[]; extern char MSG_octal_mode[]; extern char MSG_display_version[]; extern char MSG_unit_size1[]; extern char MSG_unit_size2[]; extern char MSG_unit_size4[]; extern char MSG_reposition_window[]; extern char MSG_set_mark[]; extern char MSG_goto_eob[]; extern char MSG_goto_bob[]; extern char MSG_next_buff[]; extern char MSG_prev_buff[]; extern char MSG_query_replace[]; extern char MSG_display_bindings[]; extern char MSG_auto_save[]; extern char MSG_back_unit[]; extern char MSG_compare[]; extern char MSG_forw_del_unit[]; extern char MSG_forw_unit[]; extern char MSG_link_windows[]; extern char MSG_print[]; extern char MSG_back_search[]; extern char MSG_forw_search[]; extern char MSG_back_page[]; extern char MSG_copy_region[]; extern char MSG_extended_command[]; extern char MSG_up_window[]; extern char MSG_search_again[]; extern char MSG_bind_to_key[]; extern char MSG_file_visit_split[]; extern char MSG_yank_buffer[]; extern char MSG_save_region[]; extern char MSG_use_buffer_split[]; extern char MSG_no_f_tb[]; extern char MSG_n_split[]; extern char MSG_n_combine[]; extern char MSG_show_save_buf[]; extern char MSG_scr_row[]; /* * Defined by "main.c". */ extern char ctrlg (); /* Abort out of things */ extern char quit (); /* Quit */ extern char ctlxlp (); /* Begin macro */ extern char ctlxrp (); /* End macro */ extern char ctlxe (); /* Execute macro */ extern char showversion (); /* Show version numbers, etc. */ extern char flushnquit (); /* Flush buffers & exit (fitz) */ extern char flush_all (); /* Flush buffers (jam) */ extern char autosave (); /* autosave function (jam) */ /* * Defined by "search.c". */ extern char forwsearch (); /* Search forward */ extern char backsearch (); /* Search backwards */ extern char searchagain (); /* Repeat last search command */ extern char queryrepl (); /* Query replace */ extern char compare (); /* Compare two windows */ extern char recall (); /* Recall last search string */ /* * Defined by "basic.c". */ extern char backchar (); /* Move backward by characters */ extern char forwchar (); /* Move forward by characters */ extern char gotobob (); /* Move to start of buffer */ extern char gotoeob (); /* Move to end of buffer */ extern char forwline (); /* Move forward by lines */ extern char backline (); /* Move backward by lines */ extern char forwpage (); /* Move forward by pages */ extern char backpage (); /* Move backward by pages */ extern char setmark (); /* Set mark */ extern char swapmark (); /* Swap "." and mark */ extern char gotoline (); /* Go to a specified line. */ /* * Defined by "buffer.c". */ extern char listbuffers (); /* Display list of buffers */ extern char showsavebuf (); /* Show the save buffer contents */ extern char usebuffer (); /* Switch a window to a buffer */ extern char use_buffer (); /* ditto, plus window split */ extern char killbuffer (); /* Make a buffer go away. */ extern char next_buf (); /* goto next buffer */ extern char prev_buf (); /* goto prev buffer */ extern char yank_buffer (); /* yank buffer by name */ extern char buffername (); /* change buffer name */ extern char bufsizlock (); /* lock buffer size */ /* * Defined by "file." */ extern char fileread (); /* Get a file, read only */ extern char filevisit (); /* Get a file, read write */ extern char file_visit (); /* ditto , plus window split */ extern char filewrite (); /* Write a file */ extern char filesave (); /* Save current file */ extern char filename (); /* Adjust file name */ extern char fileinsert (); /* insert file to cursor (jam ) */ extern char viewfile (); /* readonly file visit (jam) */ /* * Defined by "random.c". */ extern char dispshift (); /* Increment display shift */ extern char selfinsert (); /* Insert character */ extern char insert_toggle (); /* toggle insert mode (jam) */ extern char insertunit (); /* insert unit (pvr) */ extern char showcpos (); /* Show the cursor position */ extern char twiddle (); /* Twiddle units */ extern char forwdel (); /* Forward delete */ extern char backdel (); /* Backward delete */ extern char quote (); /* Insert literal */ extern char asciimode (); /* display ASCII data */ extern char ebcdicmode (); /* display EBCDIC data */ extern char decimalmode (); /* display DECIMAL data */ #if FLOAT_DISP extern char floatmode (); /* display FLOATING POINT data */ #endif extern char hexmode (); /* display HEX data */ extern char octalmode (); /* display OCTAL data */ extern char binarymode (); /* display BINARY data */ extern char dispsize1 (); /* display in BYTE format */ extern char dispsize2 (); /* display in WORD format */ extern char dispsize4 (); /* display in DWORD format*/ extern char dispswapbyte (); /* Display swaped bytes pvr */ extern char yank (); /* Yank back from killbuffer. */ extern char linkwind (); /* Link all windows on one buffer. */ extern char n_way_split (); /* Split buffer into n buffers. */ extern char n_way_combine (); /* Combine n buffers into one. */ /* * Defined by "region.c". */ extern char killregion (); /* Kill region. */ extern char copyregion (); /* Copy region to kill buffer. */ extern char save_region (); /* Save region in named buffer. */ /* * Defined by "spawn.c". */ extern char spawncli (); /* Run CLI in a subjob. */ extern char clock (); /* display time in modeline */ /* * Defined by "window.c". */ extern char reposition (); /* Reposition window */ extern char refresh (); /* Refresh the screen */ extern char nextwind (); /* Move to the next window */ extern char prevwind (); /* Move to the previous window */ extern char mvdnwind (); /* Move window down */ extern char mvupwind (); /* Move window up */ extern char onlywind (); /* Make current window only one */ extern char delwind (); /* Delete current window */ extern char splitwind (); /* Split current window */ extern char enlargewind (); /* Enlarge display window. */ extern char shrinkwind (); /* Shrink window. */ extern char screen_rows (); /* Set the screen size */ /* * Defined by "word.c". */ extern char backunit (); /* Backup by units */ extern char forwunit (); /* Advance by units */ extern char delfunit (); /* Delete forward unit. */ extern char delbunit (); /* Delete backward unit. */ /* * Defined by "extend.c". */ extern char extend (); /* Extended commands. */ extern char help (); /* Help key. */ extern char bindtokey (); /* Modify key bindings. */ extern char wallchart (); /* Make wall chart. */ extern void check_extend (); /* load extended key file */ extern char load_extend (); /* load extended file by name */ /* * Defined by "display.c */ extern char print (); /* print window from mark to dot */ typedef struct { short k_key; /* Key to bind. */ char (*k_funcp) (); /* Function. */ char *k_name; /* Function name string. */ char k_modify; /* modify bit */ } KEY; /* * Default key binding table. This contains * the function names, the symbol table name, and (possibly) * a key binding for the builtin functions. There are no * bindings for C-U or C-X. These are done with special * code, but should be done normally. */ KEY key[] = { KCTRL | 'A', dispshift, MSG_byte_shift, 0, KCTRL | 'B', backchar, MSG_back_char, SSRCH | SRPLC, KCTRL | 'C', quit, MSG_quit, 0, /* pvr */ KCTRL | 'D', forwdel, MSG_forw_del_char, SMOD | SSIZE | SSRCH | SRPLC, KCTRL | 'E', dispswapbyte, MSG_toggle_swap, SSRCH | SRPLC, /* pvr */ KCTRL | 'F', forwchar, MSG_forw_char, SSRCH | SRPLC, KCTRL | 'G', ctrlg, MSG_abort, SSRCH | SRPLC, KCTRL | 'I', selfinsert, MSG_ins_self, SMOD | SSRCH | SRPLC, KCTRL | 'H', backdel, MSG_back_del_char, SMOD | SSIZE | SSRCH | SRPLC, KCTRL | 'L', refresh, MSG_refresh, SSRCH | SRPLC, KCTRL | 'N', forwline, MSG_forw_line, SSRCH | SRPLC, KCTRL | 'P', backline, MSG_back_line, SSRCH | SRPLC, KCTRL | 'Q', quote, MSG_quote, 0, KCTRL | 'R', recall, MSG_recall, SSRCH | SRPLC, KCTRL | 'T', twiddle, MSG_twiddle, SMOD | SSRCH | SRPLC, KCTRL | 'V', forwpage, MSG_forw_page, SRPLC, KCTRL | 'W', killregion, MSG_kill_region, SMOD | SSIZE, KCTRL | 'Y', yank, MSG_yank, SMOD | SSIZE, KCTRL | 'Z', mvdnwind, MSG_down_window, 0, /* fitz */ KCTLX | KCTRL | 'A', insert_toggle, MSG_ins_toggle, SSRCH | SRPLC, KCTLX | KCTRL | 'B', listbuffers, MSG_display_buffers, 0, KCTLX | KCTRL | 'C', quit, MSG_quit, 0, KCTLX | KCTRL | 'E', flushnquit, MSG_exit_flush_all, 0, /* fitz */ KCTLX | KCTRL | 'F', filename, MSG_set_file_name, SMOD, /* jam */ KCTLX | KCTRL | 'I', fileinsert, MSG_file_insert, SMOD | SSIZE, KCTLX | KCTRL | 'L', bufsizlock, MSG_buf_size_lock, 0, KCTLX | KCTRL | 'M', flush_all, MSG_flush_all, 0, KCTLX | KCTRL | 'N', mvdnwind, MSG_down_window, 0, KCTLX | KCTRL | 'P', mvupwind, MSG_up_window, 0, KCTLX | KCTRL | 'R', fileread, MSG_file_read, 0, KCTLX | KCTRL | 'S', filesave, MSG_file_save, 0, KCTLX | KCTRL | 'V', filevisit, MSG_file_visit, 0, KCTLX | KCTRL | 'W', filewrite, MSG_file_write, 0, KCTLX | KCTRL | 'X', swapmark, MSG_swap_dot_and_mark, 0, KCTLX | KCTRL | 'Z', shrinkwind, MSG_shrink_window, 0, KCTLX | '=', showcpos, MSG_display_position, 0, KCTLX | '(', ctlxlp, MSG_start_macro, 0, KCTLX | ')', ctlxrp, MSG_end_macro, 0, KCTLX | '?', help, MSG_help, 0, KCTLX | '0', delwind, MSG_del_window, 0, KCTLX | '1', onlywind, MSG_only_window, 0, KCTLX | '2', splitwind, MSG_split_window, 0, KCTLX | 'B', usebuffer, MSG_use_buffer, 0, KCTLX | 'C', spawncli, MSG_spawn_cli, 0, /* fitz */ KCTLX | 'E', ctlxe, MSG_execute_macro, 0, KCTLX | 'G', gotoline, MSG_goto_line, 0, KCTLX | 'I', insertunit, MSG_ins_unit, SMOD | SSIZE | SSRCH | SRPLC, KCTLX | 'K', killbuffer, MSG_kill_buffer, 0, KCTLX | 'L', load_extend, MSG_load_bindings, 0, KCTLX | 'N', nextwind, MSG_forw_window, 0, KCTLX | 'P', prevwind, MSG_back_window, 0, KCTLX | 'V', viewfile, MSG_view_file, 0, /* jam */ KCTLX | 'Z', enlargewind, MSG_enlarge_window, 0, KMETA | KCTRL | 'A', asciimode, MSG_ascii_mode, SSRCH | SRPLC, /* pvr */ KMETA | KCTRL | 'B', binarymode, MSG_binary_mode, SSRCH | SRPLC, /* pvr */ KMETA | KCTRL | 'D', decimalmode, MSG_decimal_mode, SSRCH | SRPLC, /* pvr */ KMETA | KCTRL | 'E', ebcdicmode, MSG_ebcdic_mode, SSRCH | SRPLC, /* pvr */ #if FLOAT_DISP KMETA | KCTRL | 'F', floatmode, MSG_float_mode, SSRCH | SRPLC, /* pvr */ #endif KMETA | KCTRL | 'H', hexmode, MSG_hex_mode, SSRCH | SRPLC, /* pvr */ KMETA | KCTRL | 'K', delbunit, MSG_back_del_unit, SMOD | SSIZE | SSRCH | SRPLC, KMETA | KCTRL | 'N', buffername, MSG_buffer_name, 0, KMETA | KCTRL | 'O', octalmode, MSG_octal_mode, SSRCH | SRPLC, /* pvr */ KMETA | KCTRL | 'P', n_way_combine, MSG_n_combine, SSIZE | SMOD, /* pvr */ KMETA | KCTRL | 'R', screen_rows, MSG_scr_row, 0, /* pvr */ KMETA | KCTRL | 'S', n_way_split, MSG_n_split, 0, /* pvr */ KMETA | KCTRL | 'V', showversion, MSG_display_version, 0, KMETA | KCTRL | 'W', showsavebuf, MSG_show_save_buf, 0, KMETA | '1', dispsize1, MSG_unit_size1, SSRCH | SRPLC, /* pvr */ KMETA | '2', dispsize2, MSG_unit_size2, SSRCH | SRPLC, /* pvr */ KMETA | '4', dispsize4, MSG_unit_size4, SSRCH | SRPLC, /* pvr */ KMETA | '!', reposition, MSG_reposition_window, 0, KMETA | '.', setmark, MSG_set_mark, 0, KMETA | '>', gotoeob, MSG_goto_eob, SSRCH | SRPLC, KMETA | '<', gotobob, MSG_goto_bob, SSRCH | SRPLC, KMETA | '+', next_buf, MSG_next_buff, 0, KMETA | '-', prev_buf, MSG_prev_buff, 0, KMETA | '%', queryrepl, MSG_query_replace, SMOD, KMETA | '?', wallchart, MSG_display_bindings, 0, KMETA | 'A', autosave, MSG_auto_save, 0, KMETA | 'B', backunit, MSG_back_unit, SSRCH | SRPLC, KMETA | 'C', compare, MSG_compare, 0, KMETA | 'D', delfunit, MSG_forw_del_unit, SMOD | SSIZE | SSRCH | SRPLC, KMETA | 'F', forwunit, MSG_forw_unit, SSRCH | SRPLC, KMETA | 'G', use_buffer, MSG_use_buffer_split, 0, KMETA | 'K', bindtokey, MSG_bind_to_key, 0, KMETA | 'L', linkwind, MSG_link_windows, 0, KMETA | 'O', save_region, MSG_save_region, 0, KMETA | 'P', print, MSG_print, 0, KMETA | 'R', backsearch, MSG_back_search, 0, KMETA | 'S', forwsearch, MSG_forw_search, 0, KMETA | 'T', searchagain, MSG_search_again, 0, KMETA | 'U', file_visit, MSG_file_visit_split, 0, KMETA | 'V', backpage, MSG_back_page, SRPLC, KMETA | 'W', copyregion, MSG_copy_region, 0, KMETA | 'X', extend, MSG_extended_command, 0, KMETA | 'Y', yank_buffer, MSG_yank_buffer, SMOD | SSIZE, KMETA | 'Z', mvupwind, MSG_up_window, 0 }; #define NKEY (sizeof(key) / sizeof(key[0])) /* * Symbol table lookup. * Return a pointer to the SYMBOL node, or NULL if * the symbol is not found. */ SYMBOL * symlookup (cp) register char *cp; { register SYMBOL *sp; sp = symbol[symhash (cp)]; while (sp != NULL) { if (strcmp (cp, sp->s_name) == 0) return (sp); sp = sp->s_symp; } return (NULL); } /* * Take a string, and compute the symbol table * bucket number. This is done by adding all of the characters * together, and taking the sum mod NSHASH. The string probably * should not contain any GR characters; if it does the "*cp" * may get a nagative number on some machines, and the "%" * will return a negative number! */ int symhash (cp) register char *cp; { register int c; register int n; n = 0; while ((c = *cp++) != 0) n += c; return (n % NSHASH); } /* * Build initial keymap. The funny keys * (commands, odd control characters) are mapped using * a big table and calls to "keyadd". The printing characters * are done with some do-it-yourself handwaving. The terminal * specific keymap initialization code is called at the * very end to finish up. All errors are fatal. */ void keymapinit () { register SYMBOL *sp; register KEY *kp; register int i; for (i = 0; i < NKEYS; ++i) binding[i] = NULL; for (kp = &key[0]; kp < &key[NKEY]; ++kp) keyadd (kp->k_key, kp->k_funcp, kp->k_name, kp->k_modify); keydup (KCTLX | KCTRL | 'G', MSG_abort); keydup (KMETA | KCTRL | 'G', MSG_abort); keydup (0x7F, MSG_back_del_char); keydup (KMETA | 'Q', MSG_quote); keydup (KMETA | 0x7F, MSG_back_del_unit); /* * Should be bound by "tab" already. */ if ((sp = symlookup (MSG_ins_self)) == NULL) abort (); for (i = 0x20; i < 0x7F; ++i) { if (binding[i] != NULL) abort (); binding[i] = sp; ++sp->s_nkey; } ttykeymapinit (); } /* * Create a new builtin function "name" * with function "funcp". If the "new" is a real * key, bind it as a side effect. All errors * are fatal. */ void keyadd (new, funcp, name, modify) short new; #ifdef NOPROTO bool (*funcp) (); #else bool (*funcp) (void); #endif char *name; int modify; { register SYMBOL *sp; register int hash; if ((sp = (SYMBOL *) malloc (sizeof (SYMBOL))) == NULL) abort (); hash = symhash (name); sp->s_symp = symbol[hash]; symbol[hash] = sp; sp->s_nkey = 0; sp->s_name = name; sp->s_funcp = funcp; sp->s_modify = modify; if (new >= 0) { /* Bind this key. */ if (binding[new] != NULL) abort (); binding[new] = sp; ++sp->s_nkey; } } /* * Bind key "new" to the existing * routine "name". If the name cannot be found, * or the key is already bound, abort. */ void keydup (new, name) register int new; char *name; { register SYMBOL *sp; if (binding[new] != NULL || (sp = symlookup (name)) == NULL) { printf (MSG_no_f_tb, name); abort (); } binding[new] = sp; ++sp->s_nkey; } beav-140/tcap.c0000644000175000001440000000664605667134707013362 0ustar samusers00000000000000/* tcap: Unix V5, V7 and BS4.2 Termcap video driver for beav */ #include "def.h" #ifdef UNIX #ifdef OS2 #ifndef __EMX__ #define INCL_NOPM #define INCL_VIO #include #endif #endif #define MARGIN 8 #define SCRSIZ 64 #define NPAUSE 10 /* # times thru update to pause */ #define BEL 0x07 #define ESC 0x1B extern char *tgoto (); #ifdef NOPROTO extern int ttputc (); void putpad (); #endif #ifdef COLOR extern int tcapfcol (); extern int tcapbcol (); #endif #define TCAPSLEN 315 char tcapbuf[TCAPSLEN]; char *UP, PC, *CM, *CE, *CL, *SO, *SE, *TI, *TE; /* DR */ #ifdef BSD #include struct winsize ttysize; #endif /* BSD */ #ifdef ULTRIX struct winsize ttysize; #endif void putpad (str) char *str; { tputs (str, 1, ttputc); } void tcapopen () { char *getenv (); char *t, *p, *tgetstr (); char tcbuf[1024]; char *tv_stype; char err_str[NCOL]; #ifdef ULTRIX struct winsize ttysize; #endif nrow = NROW; if ((tv_stype = getenv ("TERM")) == NULL) #ifdef OS2 tv_stype = "ansi"; #else { puts ("Environment variable TERM not defined!\r"); ttclose (); exit (1); } #endif if ((tgetent (tcbuf, tv_stype)) != 1) { sprintf (err_str, "Unknown terminal type %s!\r", tv_stype); puts (err_str); ttclose (); /* fix in 1.13 */ exit (1); } #ifdef BSD #ifdef ULTRIX if (ioctl (0, TIOCGWINSZ, &ttysize) == 0 && ttysize.ws_row > 0) { nrow = ttysize.ws_row; } else #else if (ioctl (0, TIOCGSIZE, &ttysize) == 0 && ttysize.ts_lines > 0) { nrow = ttysize.ts_lines; } else #endif /* ULTRIX */ #endif /* BSD */ #ifndef OS2 if ((nrow = (short) tgetnum ("li") - 1) == -1) { puts ("termcap entry incomplete (lines)\r"); ttclose (); /* fix in 1.13 */ exit (1); } printf ("nrow %d, ncol %d\n", nrow, ncol); if ((ncol = (short) tgetnum ("co")) == -1) { puts ("Termcap entry incomplete (columns)\r"); ttclose (); /* fix in 1.13 */ exit (1); } /* don't allow to specify a larger number of cols than we can handle 1.13 */ if (ncol > NCOL) ncol = NCOL; #else { #ifdef __EMX__ int dst[2]; _scrsize (dst); nrow = dst[1]; ncol = dst[0]; #else VIOMODEINFO viomi; viomi.cb = sizeof (viomi); VioGetMode (&viomi, 0); nrow = viomi.row; ncol = viomi.col; #endif } #endif p = tcapbuf; t = tgetstr ("pc", &p); if (t) PC = *t; TI = tgetstr ("ti", &p); /* DR */ TE = tgetstr ("te", &p); /* DR */ CL = tgetstr ("cl", &p); CM = tgetstr ("cm", &p); CE = tgetstr ("ce", &p); UP = tgetstr ("up", &p); SO = tgetstr ("so", &p); SE = tgetstr ("se", &p); if (CL == NULL || CM == NULL || UP == NULL) { puts ("Incomplete termcap entry\r"); ttclose (); /* fix in 1.13 */ exit (1); } if (p >= &tcapbuf[TCAPSLEN]) { puts ("Terminal description too big!\r"); ttclose (); /* fix in 1.13 */ exit (1); } putpad (TI); /* DR */ } void tcapclose () /* DR */ { putpad (TE); } void tcapmove (row, col) register int row, col; { putpad (tgoto (CM, col, row)); } void tcapeeol () { putpad (CE); } void tcapeeop () { putpad (CL); } void tcaprev (state) /* change reverse video status */ int state; /* FALSE = normal video, TRUE = reverse video */ { if (state) { if (SO != NULL) putpad (SO); } else if (SE != NULL) putpad (SE); } void putnpad (str, n) char *str; int n; { tputs (str, n, ttputc); } #endif beav-140/termcap.c0000644000175000001440000001702005667134707014052 0ustar samusers00000000000000/************************************************************************ * * * Copyright (c) 1982, Fred Fish * * All Rights Reserved * * * * This software and/or documentation is released for public * * distribution for personal, non-commercial use only. * * Limited rights to use, modify, and redistribute are hereby * * granted for non-commercial purposes, provided that all * * copyright notices remain intact and all changes are clearly * * documented. The author makes no warranty of any kind with * * respect to this product and explicitly disclaims any implied * * warranties of merchantability or fitness for any particular * * purpose. * * * ************************************************************************ */ /* In order to reduce the size of this file drastically, the large * comments and pseudo code was removed as well as the padding stuff * which is not needed for OS/2. Size went from 28k down to 8k. */ #include #include #include #include static char *fgetlr(char *bp, int bpsize, FILE *fp); static FILE *find_file(char *bp); static gotcha(char *bp, char *name); static char *decode(char *bp, char **area); static char *do_esc(char *out, char *in); static void process(void); #define TRUE 1 #define FALSE 0 #define BUFSIZE 1024 /* Assumed size of external buffer */ #define NO_FILE -1 /* Returned if can't open file */ #define NO_ENTRY 0 /* Returned if can't find entry */ #define SUCCESS 1 /* Returned if entry found ok */ #define TRUNCATED 2 /* Returned if entry found but trunc */ # ifdef DGK # define DEFAULT_ROOT "termcap.cnf" /* name without path component */ FILE *fopenp(); # endif # define DEFAULT_FILE "termcap.dat" char *_tcpbuf; /* Place to remember buffer pointer */ # define index strchr static char *fgetlr(bp,bpsize,fp) char *bp; int bpsize; FILE *fp; { int numch; char *cp; if (fgets(bp,bpsize,fp) == NULL) { return(NULL); } else { numch = strlen(bp); cp = &bp[numch]; if (*--cp == '\n') { if (numch > 1 && *--cp == '\\') { *cp++ = '\n'; *cp = 0; fgetlr(cp,bpsize-numch+1,fp); } } return(bp); } } int tgetent(bp,name) char *bp; /* Pointer to buffer (1024 char min) */ char *name; /* Pointer to terminal entry to find */ { FILE *fp; *bp = 0; _tcpbuf = bp; if ((fp = find_file(bp)) == NULL) { if (*bp != 0) { return(SUCCESS); } else { return(NO_FILE); } } else { while (fgetlr(bp,BUFSIZE,fp)) { if (gotcha(bp,name)) { fclose(fp); if (bp[strlen(bp)-1] != '\n') { return(TRUNCATED); } else { return(SUCCESS); } } } return(NO_ENTRY); } } static FILE *find_file(bp) char *bp; { FILE *fp; char *cp, *ncp; if ((cp = getenv("TERMCAP")) != NULL) { if (*cp != 0) { if (*cp == '/' || *cp == '\\') { if ((fp = fopen(cp,"r")) != NULL) { return(fp); } } else { if ((ncp = getenv("TERM")) != NULL) { if (strcmp(cp,ncp) == 0) { strcpy(bp,cp); return((FILE *)NULL); } } } } } { char path[128]; _searchenv(DEFAULT_FILE, "INIT", path); if ( path[0] == 0 ) _searchenv(DEFAULT_FILE, "PATH", path); if ( path[0] == 0 ) _searchenv(DEFAULT_FILE, "DPATH", path); return(fopen(path,"r")); } } static int gotcha(bp,name) char *bp; char *name; { char *np; if (*bp == '#') { return(FALSE); } else { np = name; while (*np == *bp && *np != 0) {np++; bp++;} if (*np == 0 && (*bp == 0 || *bp == '|' || *bp == ':')) { return(TRUE); } else { while (*bp != 0 && *bp != ':' && *bp != '|') {bp++;} if (*bp != '|') { return(FALSE); } else { return(gotcha(++bp,name)); } } } } tgetflag(id) char *id; { char *bp; bp = _tcpbuf; while ((bp = index(bp,':')) != NULL) { bp++; if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) { if (*bp == 0 || *bp++ == ':') { return(TRUE); } else { return(FALSE); } } } return(FALSE); } tgetnum(id) char *id; { int value, base; char *bp; bp = _tcpbuf; while ((bp = index(bp,':')) != NULL) { bp++; if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) { if (*bp != 0 && *bp++ != '#') { return(-1); } else { value = 0; if (*bp == '0') { base = 8; } else { base = 10; } while (isdigit(*bp)) { value *= base; value += (*bp++ - '0'); } return(value); } } } return(-1); } char *tgetstr(id,area) char *id; char **area; { char *bp; char *decode(); bp = _tcpbuf; while ((bp = index(bp,':')) != NULL) { bp++; if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) { if (*bp != 0 && *bp++ != '=') { return(NULL); } else { return(decode(bp,area)); } } } return(NULL); } static char *decode(bp,area) char *bp; char **area; { char *cp, *bgn; char *do_esc(); cp = *area; while (*bp != 0 && *bp != ':') { switch(*bp) { case '\\': bp = do_esc(cp++,++bp); break; case '^': *cp++ = (char) (*++bp & 037); bp++; break; default: *cp++ = *bp++; break; } } *cp++ = 0; bgn = *area; *area = cp; return(bgn); } static char *maplist = { "E\033b\bf\fn\nr\rt\t" }; char *do_esc(out,in) char *out; char *in; { int count; char ch; char *cp; if (*in != 0) { if (isdigit(*in)) { ch = 0; for (count = 0; count < 3 && isdigit(*in); in++) { ch <<= 3; ch |= (*in - '0'); } *out++ = ch; } else if ((cp = index(maplist,*in)) != NULL) { *out++ = *++cp; in++; } else { *out++ = *in++; } } return(in); } #define MAXARGS 2 static char *in; /* Internal copy of input string pointer */ static char *out; /* Pointer to output array */ static int args[MAXARGS]; /* Maximum number of args to convert */ static int pcount; /* Count of args processed */ static char output[64]; /* Converted string */ char *tgoto(cm,destcol,destline) char *cm; int destcol; int destline; { if (cm == NULL) { return("OOPS"); } else { in = cm; out = output; args[0] = destline; args[1] = destcol; pcount = 0; while (*in != 0) { if (*in != '%') { *out++ = *in++; } else { process(); } } *out++ = 0; return(output); } } static void process() { int temp; in++; switch(*in++) { case 'd': sprintf(out,"%d",args[pcount++]); out = &output[strlen(output)]; break; case '2': sprintf(out,"%02d",args[pcount++]); out = &output[strlen(output)]; break; case '3': sprintf(out,"%03d",args[pcount++]); out = &output[strlen(output)]; break; case '.': *out++ = (char) args[pcount++]; break; case '+': *out++ = (char) args[pcount++] + *in++; break; case '>': if (args[pcount] > (int) *in++) { args[pcount] += *in++; } else { in++; } break; case 'r': temp = args[pcount]; args[pcount] = args[pcount+1]; args[pcount+1] = temp; break; case 'i': args[pcount]++; args[pcount+1]++; break; case '%': *out++ = '%'; break; } } void tputs(cp,affcnt,outc) char *cp; int affcnt; int (*outc)(int); { int ptime; /* Pad time in tenths of milliseconds */ if (cp == NULL || *cp == 0) { return; } else { for (ptime = 0; isdigit(*cp); cp++) { ptime *= 10; ptime += (*cp - '0'); } ptime *= 10; if (*cp == '.') { cp++; if (isdigit(*cp)) { ptime += (*cp++ - '0'); } while (isdigit(*cp)) {cp++;} } if (*cp == '*') { ptime *= affcnt; cp++; } while (*cp != 0) { (*outc)(*cp++); } } } beav-140/termcap.dat0000644000175000001440000001034105667134707014377 0ustar samusers00000000000000# PC termcap for OS/2 and MS-DOS # ansi|ANSI color:\ :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\ :cl=\E[H\E[2J:ce=\E[K:\ :ho=\E[H:cm=\E[%i%d;%dH:\ :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ :ti=\E[0;30;46m\E[=7l:te=\E[0m\E[=7h:\ :so=\E[0;31;47m:se=\E[0;30;46m:\ :us=\E[1;31;46m:ue=\E[0;30;46m:\ :mb=\E[5m:md=\E[0;31;46m:\ :mr=\E[1;37;46m:me=\E[0;30;46m:\ :aw: # window|ANSI PM window:\ :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\ :cl=\E[H\E[2J:ce=\E[K:\ :ho=\E[H:cm=\E[%i%d;%dH:\ :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ :ti=\E[0;30;47m\E[=7l:te=\E[0;30;47m\E[=7h:\ :so=\E[0;36;47m:se=\E[0;30;47m:\ :us=\E[0;31;47m:ue=\E[0;30;47m:\ :mb=\E[5m:md=\E[1;37;47m:\ :mr=\E[0;30;46m:me=\E[0;30;47m:\ :aw: # mono|ANSI mono:\ :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\ :cl=\E[H\E[2J:ce=\E[K:\ :ho=\E[H:cm=\E[%i%d;%dH:\ :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ :ti=\E[0m\E[=7l:te=\E[0m\E[=7h:\ :so=\E[1m:se=\E[m:us=\E[4m:ue=\E[m:\ :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m: # # This is a termcap for NNANSI.SYS (New & Improved NANSI.SYS), # a faster and more complete public domain replacement for # ANSI.SYS, and two other ANSI.SYS replacements, NANSI.SYS and # ZANSI.SYS. # # NANSI and ZANSI support line insert (al) and delete (dl) # and character insert (ic) and delete (dc) where ANSI.SYS # does not. NNANSI.SYS also supports clear to end of display # (cd), does reverse video (mr) properly, and emulates SGR # more fully, allowing correct end sequences for standout (se) # and end of underline (ue). # nnansi|ibmpc|NNANSI color:\ :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\ :cl=\E[2J:cd=\E[J:ce=\E[K:\ :ho=\E[H:cm=\E[%i%d;%dH:\ :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ :ti=\E[0;30;46m\E[=7l:te=\E[0m\E[=7h:\ :so=\E[0;30;47m:se=\E[0;30;46m:\ :us=\E[1;31;46m:ue=\E[0;30;46m:\ :mb=\E[5m:md=\E[0;31;46m:me=\E[0;30;46m:\ :mh=\E[2m:mr=\E[0;31;46m:\ :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:\ :aw: # nnansi-mono|NNANSI mono:\ :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\ :cl=\E[2J:cd=\E[J:ce=\E[K:\ :ho=\E[H:cm=\E[%i%d;%dH:\ :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ :ti=\E[=7l:te=\E[0m\E[=7h:\ :so=\E[1m:se=\E[2m:\ :us=\E[4m:ue=\E[24m:\ :mb=\E[5m:md=\E[1m:mh=\E[2m:mr=\E[7m:me=\E[m:\ :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P: # nansi|zansi|N/ZANSI color:\ :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\ :cl=\E[2J:ce=\E[K:\ :ho=\E[H:cm=\E[%i%d;%dH:\ :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ :ti=\E[0;44m:te=\E[0m:\ :so=\E[1;35;44m:se=\E[0;44m:\ :us=\E[1;31;44m:ue=\E[0;44m:\ :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[0;44m:\ :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P: # nansi-mono|zansi-mono|N/ZANSI mono:\ :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\ :cl=\E[2J:ce=\E[K:\ :ho=\E[H:cm=\E[%i%d;%dH:\ :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ :ti=\E[0m:te=\E[0m:\ :so=\E[1;35m:se=\E[0m:\ :us=\E[1;31m:ue=\E[0m:\ :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:\ :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P: # # For really complete ANSI emulations (FANSI-CONSOLE?): # AX|ANSI X3.64|full ANSI X3.64 (1977) standard:\ :co#80:li#24:bs:pt:am:mi:bl=^G:le=^H:\ :cl=\E[2J:ce=\E[K:cd=\E[J:\ :ho=\E[H:cm=\E[%i%d;%dH:cs=\E[%i%d;%dr:\ :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ :UP=\E[%dA:DO=\E[%dB:LE=\E[%dC:RI=\E[%dD:\ :so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:\ :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:as=^N:ae=^O:\ :ku=\E[A:kd=\E[B:kl=\E[C:kr=\E[D:kb=^H:\ :kn#4:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\ :im=\E[4h:ei=\E[4l:al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:sf=\ED:sr=\EM: # # Display hacker's tool # debug|debugging entry:\ :ae=:AL=:al=:am:as=:bl=:bs:bt=:bw:CC=:\ :cd=:ce=:ch=:cl=:cm=:co#80:cr=:\ :cs=:ct=:cv=:da:db:DC=:dc=:DL=:\ :dl=
:dm=:DO=:do=:ds=:ec=:ed=:ei=:\ :es:fs=:ho=:hs:IC=:ic=:im=:ip=:is=:\ :it#8:ke=:LE=:le=:li#24:ll=:mb=:md=:me=:\ :mh=:mi:mk=:mm=:mo=:mp=:mr=:ms=:nd=:\ :nw=:pc=:pf=:pO=:po=:ps=:rc=:RI=:\ :rp=:rs=:sc=:se=:SF=:sf=:so=:\ :SR=:sr=:st=:ta=:te=:ti=:uc=:ue=:\ :UP=:up=:us=:vb=:ve=:vi=:vs=: # dumb:\ :am:bl=^G:co#80:do=^J:nl=^M^J: # # End beav-140/termcap.h0000644000175000001440000000203505667134707014057 0ustar samusers00000000000000/************************************************************************ * * * Copyright (c) 1982, Fred Fish * * All Rights Reserved * * * * This software and/or documentation is released for public * * distribution for personal, non-commercial use only. * * Limited rights to use, modify, and redistribute are hereby * * granted for non-commercial purposes, provided that all * * copyright notices remain intact and all changes are clearly * * documented. The author makes no warranty of any kind with * * respect to this product and explicitly disclaims any implied * * warranties of merchantability or fitness for any particular * * purpose. * * * ************************************************************************/ extern int tgetent(char *bp, char *name); extern int tgetflag(char *id); extern int tgetnum(char *id); extern char *tgetstr(char *id, char **area); extern char *tgoto(char *cm, int destcol, int destline); extern void tputs(char *cp, int affcnt, int (*outc)(int)); beav-140/termio.c0000644000175000001440000001752105667134707013724 0ustar samusers00000000000000/* * The functions in this file negotiate with the operating system for * characters, and write characters in a barely buffered fashion on the display. * All operating systems. */ #include /* 1.13 */ #ifdef UNIX /* System V */ #include #include #ifdef BSD #include #else #ifdef OS2 #ifndef __EMX__ #define INCL_NOPM #define INCL_DOS #define INCL_KBD #include #endif #include #else #ifdef MINIX #include #define O_NDELAY O_NONBLOCK #else #include #endif /* MINIX */ #endif /* OS2 */ #endif /* BSD */ #include #include #include "def.h" int kbdflgs; /* saved keyboard fd flags */ int kbdpoll; /* in O_NDELAY mode */ int kbdqp; /* there is a char in kbdq */ char kbdq; /* char we've already read */ #ifdef BSD struct sgttyb otermb; struct sgttyb ntermb; #else #ifdef OS2 #ifndef __EMX__ KBDINFO kbst, kbst_std; #endif #else #ifdef MINIX struct sgttyb otermio; /* original terminal characteristics */ struct sgttyb ntermio; /* charactoristics to use inside */ struct tchars tchars, tcharsorig; #else struct termio otermio; /* original terminal characteristics */ struct termio ntermio; /* charactoristics to use inside */ #endif /* MINIX */ #endif /* OS2 */ #endif /* BSD */ #ifndef OS2 extern errno; /* System error number -- Necessary when compiling in BSD 1.13 */ #endif int nrow; /* Terminal size, rows. */ int ncol; /* Terminal size, columns. */ /* * This function is called once to set up the terminal device streams. * On VMS, it translates TT until it finds the terminal, then assigns * a channel to it and sets it raw. On CPM it is a no-op. */ void ttopen () { #ifdef BSD #ifdef ULTRIX struct winsize ttysize; #else struct ttysize ttysize; #endif ioctl (0, TIOCGETP, &otermb); /* save settings */ ntermb = otermb; /* setup new settings */ ntermb.sg_flags &= ~ECHO; ntermb.sg_flags |= RAW; ioctl (0, TIOCSETP, &ntermb); /* and activate them */ kbdpoll = FALSE; /* on all screens we are not sure of the initial position of the cursor */ ttrow = 999; ttcol = 999; #ifdef ULTRIX if (ioctl (0, TIOCGWINSZ, &ttysize) == 0) { nrow = ttysize.ws_row; ncol = ttysize.ws_col; #else if (ioctl (0, TIOCGSIZE, &ttysize) == 0) { nrow = ttysize.ts_lines; ncol = ttysize.ts_cols; #endif } else { nrow = NROW; ncol = NCOL; } #else #ifdef OS2 setmode (1, O_BINARY); #else #ifdef MINIX ioctl (0, TIOCGETP, &otermio); ntermio = otermio; ntermio.sg_flags &= ~ECHO; ntermio.sg_flags |= RAW; ioctl (0, TIOCSETP, &ntermio); ioctl (0, TIOCGETC, &tcharsorig); tchars = tcharsorig; tchars.t_intrc = tchars.t_quitc = tchars.t_startc = tchars.t_stopc = tchars.t_eofc = tchars.t_brkc = -1; ioctl (0, TIOCSETC, &tchars); #else ioctl (0, TCGETA, &otermio);/* save old settings */ ntermio.c_iflag = 0; /* setup new settings */ ntermio.c_oflag = 0; ntermio.c_cflag = otermio.c_cflag; ntermio.c_lflag = 0; ntermio.c_line = otermio.c_line; ntermio.c_cc[VMIN] = 1; ntermio.c_cc[VTIME] = 0; ioctl (0, TCSETAW, &ntermio); /* and activate them */ #endif /* MINIX */ kbdflgs = fcntl (0, F_GETFL, 0); kbdpoll = FALSE; #endif /* OS2 */ /* on all screens we are not sure of the initial position of the cursor */ ttrow = 999; ttcol = 999; nrow = NROW; ncol = NCOL; #endif /* BSD */ } /* * This function gets called just before we go back home to the command * interpreter. On VMS it puts the terminal back in a reasonable state. * Another no-operation on CPM. */ void ttclose () { #ifdef BSD if (ioctl (0, TIOCSETP, &otermb) == -1) /* restore terminal settings */ printf ("closing ioctl on dev 0 failure, error = %d\n", errno); #else #ifdef OS2 setmode (1, O_TEXT); #else #ifdef MINIX if (ioctl (0, TIOCSETP, &otermio) == -1 || ioctl (0, TIOCSETC, &tcharsorig) == -1) printf ("closing ioctl on dev 0 failure, error = %d\n", errno); #else if (ioctl (0, TCSETAW, &otermio) == -1) /* restore terminal settings */ printf ("closing ioctl on dev 0 failure, error = %d\n", errno); #endif /* MINIX */ if (fcntl (0, F_SETFL, kbdflgs) == -1) printf ("closing fcntl on dev 0 failure, error = %d\n", errno); #endif /* OS2 */ #endif /* BSD */ } #ifdef OS2 void ttraw (void) { #ifdef __32BIT__ signal (SIGINT, SIG_IGN); signal (SIGBREAK, SIG_IGN); #else PFNSIGHANDLER oldhandler; USHORT oldact; DosSetSigHandler ((PFNSIGHANDLER) NULL, &oldhandler, &oldact, SIGA_IGNORE, SIG_CTRLBREAK); DosSetSigHandler ((PFNSIGHANDLER) NULL, &oldhandler, &oldact, SIGA_IGNORE, SIG_CTRLC); #endif #ifndef __EMX__ kbst_std.cb = sizeof (kbst_std); KbdGetStatus (&kbst_std, 0); kbst = kbst_std; kbst.fsMask &= ~(KEYBOARD_ECHO_ON | KEYBOARD_ASCII_MODE | KEYBOARD_SHIFT_REPORT); kbst.fsMask |= (KEYBOARD_ECHO_OFF | KEYBOARD_BINARY_MODE); KbdSetStatus (&kbst, 0); #endif } void ttcooked (void) { #ifndef __EMX__ KbdSetStatus (&kbst_std, 0); #endif } #endif /* * Write a character to the display. On VMS, terminal output is buffered, and * we just put the characters in the big array, after checking for overflow. * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on * MS-DOS (use the very very raw console output routine). */ #ifdef OS2 int tty_io_size = 0; char tty_io_buffer[2048]; #endif int ttputc (c) { #ifdef OS2 if (tty_io_size == sizeof (tty_io_buffer)) { write (1, tty_io_buffer, tty_io_size); tty_io_size = 0; } tty_io_buffer[tty_io_size++] = c; #else fputc (c, stdout); #endif return c; } /* * Flush terminal buffer. Does real work where the terminal output is buffered * up. A no-operation on systems where byte at a time terminal I/O is done. */ void ttflush () { #ifdef OS2 if (tty_io_size) { write (1, tty_io_buffer, tty_io_size); tty_io_size = 0; } #else fflush (stdout); #endif } /* * Read a character from the terminal, performing no editing and doing no echo * at all. More complex in VMS that almost anyplace else, which figures. Very * simple on CPM, because the system can do exactly what you want. */ #ifdef OS2 #ifdef __EMX__ static int chr = -1; #endif #endif ttgetc () { #ifdef OS2 #ifdef __EMX__ if (chr != -1) { int c = chr; chr = -1; return c; } else return _read_kbd (0, 1, 0); #else static int ext, scan, chr; KBDKEYINFO ki; if (ext) { ext = 0; return scan; } else { ttflush (); KbdCharIn (&ki, IO_WAIT, 0); if (ki.chChar == 0 || ki.chChar == 0xE0) { ext = 1; scan = ki.chScan; return 0xE0; } else return ki.chChar; } #endif #else if (kbdqp) kbdqp = FALSE; else { #ifdef BSD int count; if (kbdpoll && (ioctl (0, FIONREAD, &count), count == 0)) return FALSE; read (0, &kbdq, 1); #else if (kbdpoll && fcntl (0, F_SETFL, kbdflgs) < 0) return FALSE; kbdpoll = FALSE; while (read (0, &kbdq, 1) != 1) ; #endif } return (kbdq & 127); #endif /* OS2 */ } /* typahead(): Check to see if any characters are already in the keyboard buffer */ ttkeyready () { #ifdef OS2 #ifdef __EMX__ chr = _read_kbd (0, 0, 0); return (chr != -1); #else KBDKEYINFO ki; KbdPeek (&ki, 0); return (ki.fbStatus != 0); #endif #else if (!kbdqp) { #ifdef BSD int count; if (!kbdpoll && (ioctl (0, FIONREAD, &count), count == 0)) return FALSE; kbdpoll = TRUE; /* fix in 1.13 */ kbdqp = TRUE; #else #ifdef X_MINIX /* MINIX has non-blocking mode but it doesn't work !?!? */ return FALSE; #else if (!kbdpoll && fcntl (0, F_SETFL, kbdflgs | O_NDELAY) < 0) return (FALSE); kbdpoll = TRUE; /* fix in 1.13 */ kbdqp = (1 == read (0, &kbdq, 1)); #endif /* MINIX */ #endif /* BSD */ } return (kbdqp); #endif /* OS2 */ } #endif beav-140/text.c0000644000175000001440000000264505667134707013412 0ustar samusers00000000000000/* * This file contains all text srtings that should not be changed */ #include "def.h" /* in basic.c */ char MSG_lX[] = "%lX"; char MSG_lO[] = "%lo"; char MSG_lD[] = "%ld"; /* in buffer.c */ char MSG_up_arrow[] = "^"; char MSG_null[] = ""; /* in display.c */ char MSG_disp_r_n[] = "\r\n"; char MSG_11lX[] = "%11lX:"; char MSG_11lo[] = "%11lo:"; char MSG_11ld[] = "%11ld:"; char MSG_03o[] = "%03o"; char MSG_06o[] = "%06o"; char MSG_011lo[] = "%011lo"; char MSG_03u[] = "%03u"; char MSG_05u[] = "%05u"; char MSG_010lu[] = "%010lu"; char MSG_116e[] = "%+1.16e"; char MSG_02X[] = "%02X"; char MSG_04X[] = "%04X"; char MSG_08lX[] = "%08lX"; char MSG_siz_8[] = " 8 "; char MSG_siz_16[] = " 16"; char MSG_siz_32[] = " 32"; char MSG_siz_null[] = " "; char MSG_int_shift[] = " S%X"; char MSG_mot_shift[] = " %X"; /* in echo.c */ char MSG_hex_dig[] = "0123456789ABCDEF"; /* in format.c */ char hex_str[] = "%X"; char hex_l_str[] = "%lX"; char octal_str[] = "%o"; char octal_l_str[] = "%lo"; char decimal_str[] = "%u"; char decimal_l_str[] = "%lu"; char float_str[] = "%e"; char char_str[] = "%c"; char MSG_init_file[] = "beav.ini"; char MSG_init_var[] = "INIT"; char MSG_init_path[] = "PATH"; /* in random.c */ char MSG_3u[] = "%3u"; char MSG_5u[] = "%5u"; char MSG_lu[] = "%lu"; char MSG_key_code[] = "%s, %s"; char MSG_cnt_rd[] = "ERROR: Cannot open file for reading"; beav-140/tty.c0000644000175000001440000001071105667134707013237 0ustar samusers00000000000000/* * Wang PC terminal display TTY.C * */ #include "def.h" void ttinit (); void tttidy (); void ttmove (); void tteeol (); void tteeop (); void ttbeep (); void asciiparm (); void ttnowindow (); /* stub */ void ttcolor (); extern void tcapopen (); extern void tcapclose (); /* DR */ extern void tcapmove (); #ifdef MSDOS #include "dos.h" extern bool ibm_pc, mem_map; #endif #define BEL 0x07 /* BEL character. */ #define ESC 0x1B /* ESC character. */ extern int ttrow; extern int ttcol; extern int tttop; extern int ttbot; extern int tthue; int tceeol = 3; /* Costs. */ /* * Initialize the terminal when the editor * gets started up. */ void ttinit () { #ifdef MSDOS ttraw (); #endif #ifdef OS2 ttraw (); #endif #ifdef UNIX tcapopen (); tcapmove (0, 0); tcapeeop (); #endif } /* * Clean up the terminal, in anticipation of * a return to the command interpreter. */ void tttidy () { #ifdef MSDOS ttcooked (); #endif #ifdef OS2 ttcooked (); #endif #ifdef UNIX tcapclose (); #endif } /* * Move the cursor to the specified * origin 0 row and column position. Try to * optimize out extra moves; redisplay may * have left the cursor in the right * location last time! */ void ttmove (row, col) int row, col; { #ifdef MSDOS union REGS regs; /* Move in both axes */ if (ibm_pc) { regs.h.ah = 2; regs.h.dh = (char) row; regs.h.dl = (char) col; regs.h.bh = 0; int86 (0x10, ®s, ®s); /* set cursor position */ } else #endif #ifdef UNIX tcapmove (row, col); #endif #ifdef ANSI { ttputc (ESC); ttputc ('['); asciiparm (row + 1); ttputc (';'); asciiparm (col + 1); ttputc ('H'); } #endif ttrow = row; ttcol = col; } /* * Erase to end of line. */ void tteeol () { char col, row, i; #ifdef MSDOS union REGS regs; if (ibm_pc) { regs.h.ah = 3; regs.h.bh = 0; int86 (0x10, ®s, ®s); /* get cursor position */ col = regs.h.dl; row = regs.h.dh; for (i = col; i < (NCOL - 1); i++) { regs.h.ah = 0x0e; regs.h.bl = 0; regs.h.bh = 0; regs.h.al = ' '; int86 (0x10, ®s, ®s); /* set cursor position */ } /* put cursor back to original position */ regs.h.ah = 2; regs.h.bh = 0; regs.h.dl = col; regs.h.dh = row; int86 (0x10, ®s, ®s); /* get cursor position */ } else #endif #ifdef ANSI { ttputc (ESC); ttputc ('['); #ifdef MSDOS if (ibm_pc) ttputc ('0'); /* this is necessary in IBM PC's */ #endif ttputc ('K'); } #endif #ifdef UNIX tcapeeol (); #endif } /* * Erase to end of page. * only ever used when cursor is at 0,0, so IBM screen erase * is same as eop */ void tteeop () { #ifdef MSDOS union REGS regs; char i, j; if (ibm_pc) { regs.h.ah = 6; regs.h.al = 0; regs.x.cx = 0; regs.x.dx = (nrow << 8) | (NCOL - 1); int86 (0x10, ®s, ®s); /* scroll to clear screen */ } else #endif #ifdef ANSI { ttcolor (CTEXT); ttputc (ESC); ttputc ('['); #ifdef MSDOS if (ibm_pc) ttputc ('0'); else #endif ttputc ('2'); ttputc ('J'); } #endif #ifdef UNIX tcapeeop (); #endif } /* * Make a noise. */ void ttbeep () { ttputc (BEL); ttflush (); } /* * Convert a number to decimal * ascii, and write it out. Used to * deal with numeric arguments. */ void asciiparm (n) register int n; { register int q; q = n / 10; if (q != 0) asciiparm (q); ttputc ((n % 10) + '0'); } /* * Switch to full screen scroll. This is * used by "spawn.c" just before is suspends the * editor, and by "display.c" when it is getting ready * to exit. This is a no-op. */ void ttnowindow () { } /* * Set the current writing color to the * specified color. Watch for color changes that are * not going to do anything (the color is already right) * and don't send anything to the display. */ void ttcolor (color) register int color; { #ifdef MSDOS if (mem_map) { tthue = color; /* Save the color. */ return; } #endif #ifdef UNIX if (color == CTEXT) tcaprev (FALSE); else tcaprev (TRUE); tthue = color; /* Save the color. */ #endif #ifdef ANSI if (color != tthue) { if (color == CTEXT) { /* Normal video. */ ttputc (ESC); ttputc ('['); ttputc ('0'); ttputc ('m'); } else if (color == CMODE) { /* Reverse video. */ ttputc (ESC); ttputc ('['); ttputc ('7'); ttputc ('m'); } tthue = color; /* Save the color. */ } #endif } beav-140/ttyio.c0000644000175000001440000000761505667134707013600 0ustar samusers00000000000000/* * * MS-DOS terminal I/O. TTYIO.C */ #include "def.h" #ifdef MSDOS void ttopen (); void ttclose (); /* stub */ int ttputc (); void putline (); void ttflush (); /* stub */ int ttkeyready (); int ttgetc (); void ttraw (); void ttcooked (); void set_crt_type (); #include "dos.h" int slot; int scr_type; #define SCREEN_PORT (video_port) static int video_port = { 0x1010 }; extern bool wang_pc; extern bool ibm_pc; int nrow; /* Terminal size, rows. */ int ncol; /* Terminal size, columns. */ int last_key; uchar attr = 0x0f; /* saved color attribute, default * white on black */ /* * Initialization. * for MS-DOS. */ void ttopen () { uchar *ptr; uchar data[64]; if (wang_pc && !ibm_pc) set_crt_type (); nrow = NROW; ncol = NCOL; if (ibm_pc) { union REGS inregs, outregs; struct SREGS segs; int i; for (i = 0; i < 64; i++) data[i] = 0; ptr = data; inregs.h.ah = 0x1b; inregs.h.al = 0; inregs.x.bx = 0; inregs.x.di = (int) data; #ifdef FP_SEG /* this is for MSC 5.1 */ segs.es = FP_SEG (ptr); #else /* this is for MSC 6.0 or 7.0 */ segs.es = _FP_SEG (ptr); #endif int86x (0x10, &inregs, &outregs, &segs); /* get number of rows */ /* if that failed then use the default */ if ((outregs.h.al != 0x1b) || (data[0x22] == 0)) return; nrow = data[0x22]; /* get current attributes */ inregs.h.ah = 0x8; inregs.h.al = 0; inregs.h.bh = 0; int86 (0x10, &inregs, &outregs); attr = outregs.h.ah & 0x7f; /* don't want blink */ } } void ttclose () { } void ttflush () { } /* * Write character. */ int ttputc (c) int c; { bdos (6, c, 0); return c; } void putline (row, startcol, stringsize, string) int row, startcol, stringsize; char *string; { extern int tthue; unsigned short *screen; int x, attribute; char c_row, c_col, i; union REGS regs; if (ibm_pc) { c_row = row - 1; c_col = startcol - 1; for (i = 0; i < stringsize; i++) { regs.h.ah = 2; regs.h.dh = c_row; regs.h.dl = c_col; regs.h.bh = 0; int86 (0x10, ®s, ®s); /* set cursor position */ if (tthue == CTEXT) regs.h.bl = attr; if (tthue == CMODE) regs.h.bl = ((0x70 & attr) >> 4) | ((0x07 & attr) << 4); regs.h.ah = 9; regs.h.bh = 0; regs.h.al = string[i]; regs.x.cx = 1; int86 (0x10, ®s, ®s); /* set cursor position */ c_col++; } } else if (wang_pc) { if (tthue == CTEXT) attribute = 0x00; else attribute = 0x02; x = stringsize; screen = (unsigned short *) WANG_CHARACTER_SCREEN; screen += ((row - 1) * 80) + startcol - 1; outp (SCREEN_PORT, 01); while (x--) { *screen = (*string++ << 8) | attribute; screen++; } outp (SCREEN_PORT, 00); } } /* * return with a TRUE if key was struck. */ int ttkeyready () { int cnt; if (last_key != 0) return (1); last_key = bdos (6, 0xff, 0); last_key &= 0xff; if (last_key == 0) return (0); else return (1); } /* * Read character. */ int ttgetc () { int c; if (last_key != 0) { c = last_key; last_key = 0; return (c); } ttcooked (); c = (bdos (7, 0, 0) & 0xFF); ttraw (); return (c); } /* disable nasty cntrl-c during disk io! */ void ttraw () { union REGS inregs, outregs; inregs.h.al = 1; inregs.h.ah = 0x33; inregs.h.dl = 0; intdos (&inregs, &outregs); /* cntrlcoff(); */ } /* re enable cntrl-c for keyboard */ void ttcooked () { union REGS inregs, outregs; inregs.h.al = 1; inregs.h.ah = 0x33; intdos (&inregs, &outregs); inregs.h.dl = 1; /* cntrlcon(); */ } /* switch physical monitors */ static char str[] = { 0x1b, '/', 1, 's' }; void set_crt_type () { char active_screen; active_screen = getscreenstate (); slot = active_screen & 0x0f; scr_type = (active_screen & 0x70) >> 4; video_port = 0x1010 | (slot << 8); } #endif beav-140/ttykbd.c0000644000175000001440000003613105667134707013724 0ustar samusers00000000000000/* * Wang PC keyboard handler */ #include "def.h" extern char MSG_sp_key[]; extern char MSG_byte_shift[]; extern char MSG_back_char[]; extern char MSG_quit[]; extern char MSG_forw_del_char[]; extern char MSG_toggle_swap[]; extern char MSG_forw_char[]; extern char MSG_abort[]; extern char MSG_ins_self[]; extern char MSG_back_del_char[]; extern char MSG_refresh[]; extern char MSG_forw_line[]; extern char MSG_back_line[]; extern char MSG_quote[]; extern char MSG_recall[]; extern char MSG_twiddle[]; extern char MSG_forw_page[]; extern char MSG_kill_region[]; extern char MSG_yank[]; extern char MSG_down_window[]; extern char MSG_ins_toggle[]; extern char MSG_display_buffers[]; extern char MSG_quit[]; extern char MSG_exit_flush_all[]; extern char MSG_set_file_name[]; extern char MSG_file_insert[]; extern char MSG_buf_size_lock[]; extern char MSG_flush_all[]; extern char MSG_down_window[]; extern char MSG_up_window[]; extern char MSG_file_read[]; extern char MSG_file_save[]; extern char MSG_file_visit[]; extern char MSG_file_write[]; extern char MSG_swap_dot_and_mark[]; extern char MSG_shrink_window[]; extern char MSG_display_position[]; extern char MSG_start_macro[]; extern char MSG_end_macro[]; extern char MSG_help[]; extern char MSG_only_window[]; extern char MSG_split_window[]; extern char MSG_use_buffer[]; extern char MSG_spawn_cli[]; extern char MSG_execute_macro[]; extern char MSG_goto_line[]; extern char MSG_ins_unit[]; extern char MSG_kill_buffer[]; extern char MSG_load_bindings[]; extern char MSG_forw_window[]; extern char MSG_back_window[]; extern char MSG_view_file[]; extern char MSG_enlarge_window[]; extern char MSG_ascii_mode[]; extern char MSG_binary_mode[]; extern char MSG_buffer_name[]; extern char MSG_decimal_mode[]; extern char MSG_hex_mode[]; extern char MSG_back_del_unit[]; extern char MSG_octal_mode[]; extern char MSG_display_version[]; extern char MSG_unit_size1[]; extern char MSG_unit_size2[]; extern char MSG_unit_size4[]; extern char MSG_reposition_window[]; extern char MSG_set_mark[]; extern char MSG_goto_eob[]; extern char MSG_goto_bob[]; extern char MSG_next_buff[]; extern char MSG_prev_buff[]; extern char MSG_query_replace[]; extern char MSG_display_bindings[]; extern char MSG_auto_save[]; extern char MSG_back_unit[]; extern char MSG_compare[]; extern char MSG_forw_del_unit[]; extern char MSG_forw_unit[]; extern char MSG_link_windows[]; extern char MSG_print[]; extern char MSG_back_search[]; extern char MSG_forw_search[]; extern char MSG_back_page[]; extern char MSG_copy_region[]; extern char MSG_extended_command[]; extern char MSG_up_window[]; extern char MSG_search_again[]; extern char MSG_bind_to_key[]; extern char MSG_file_visit_split[]; extern char MSG_yank_buffer[]; extern char MSG_save_region[]; extern char MSG_use_buffer_split[]; extern char MSG_no_f_tb[]; #define SPECIAL 0x1F /* Special keys */ typedef struct key_name_array { int key_code; char *func_name_str; char *key_name_str; } KEY_NAME_ARRAY; #if MSDOS extern bool wang_pc; extern bool ibm_pc; #endif /* * The keyboard's special characters, those things that are prefixed with * a 0x1F, are placed into the keyboard tables as KCTRL || 0x800 || x, for some * x i.e. they have both the control and 0x800 bits set, so they won't conflict * with anything else on the keyboard. */ /* * Names for the keys with basic keycode * between KFIRST and KLAST (inclusive). This is used by * the key name routine in "kbd.c". */ #if MSDOS KEY_NAME_ARRAY wang_keys[] = { KCTRL | KFIRST | 0x00, MSG_bind_to_key, "Indent", /* KCTRL | KFIRST | 0x01, NULL, "Page", */ KCTRL | KFIRST | 0x02, MSG_reposition_window, "Center", /* KCTRL | KFIRST | 0x03, NULL, "DecTab", */ /* KCTRL | KFIRST | 0x04, NULL, "Format", */ /* KCTRL | KFIRST | 0x05, NULL, "Merge", */ /* KCTRL | KFIRST | 0x06, NULL, "Note", */ KCTRL | KFIRST | 0x07, MSG_set_mark, "Stop", KCTRL | KFIRST | 0x08, MSG_forw_search, "Search", KCTRL | KFIRST | 0x09, MSG_yank, "Replace", KCTRL | KFIRST | 0x0A, MSG_copy_region, "Copy", KCTRL | KFIRST | 0x0B, MSG_kill_region, "Move", KCTRL | KFIRST | 0x0C, MSG_extended_command, "Command", KCTRL | KFIRST | 0x0D, MSG_forw_window, "UpDown", /* KCTRL | KFIRST | 0x0E, NULL, "BlankKey", */ KCTRL | KFIRST | 0x0F, MSG_goto_line, "GoTo", /* KCTRL | KFIRST | 0x10, NULL, "Sh-Indent", */ /* KCTRL | KFIRST | 0x11, NULL, "Sh-Page", */ /* KCTRL | KFIRST | 0x12, NULL, "Sh-Center", */ /* KCTRL | KFIRST | 0x13, NULL, "Sh-DecTab", */ /* KCTRL | KFIRST | 0x14, NULL, "Sh-Format", */ /* KCTRL | KFIRST | 0x15, NULL, "Sh-Merge", */ /* KCTRL | KFIRST | 0x16, NULL, "Sh-Note", */ /* KCTRL | KFIRST | 0x17, NULL, "Sh-Stop", */ KCTRL | KFIRST | 0x18, MSG_search_again, "Sh-Search", KCTRL | KFIRST | 0x19, MSG_query_replace, "Sh-Replace", /* KCTRL | KFIRST | 0x1A, NULL, "Sh-Copy", */ /* KCTRL | KFIRST | 0x1B, NULL, "Sh-Move", */ /* KCTRL | KFIRST | 0x1C, NULL, "Sh-Command", */ KCTRL | KFIRST | 0x1D, MSG_split_window, "Sh-UpDown", /* KCTRL | KFIRST | 0x1E, NULL, "Sh-BlankKey", */ /* KCTRL | KFIRST | 0x1F, NULL, "Sh-GoTo", */ KCTRL | KFIRST | 0x40, MSG_back_line, "North", KCTRL | KFIRST | 0x41, MSG_forw_char, "East", KCTRL | KFIRST | 0x42, MSG_forw_line, "South", KCTRL | KFIRST | 0x43, MSG_back_char, "West", KCTRL | KFIRST | 0x44, MSG_byte_shift, "Home", /* KCTRL | KFIRST | 0x45, NULL, "Execute", */ KCTRL | KFIRST | 0x46, MSG_ins_toggle, "Insert", KCTRL | KFIRST | 0x47, MSG_forw_del_char, "Delete", KCTRL | KFIRST | 0x48, MSG_back_page, "PrevPage", KCTRL | KFIRST | 0x49, MSG_forw_page, "NextPage", /* KCTRL | KFIRST | 0x4B, NULL, "Erase", */ /* KCTRL | KFIRST | 0x4D, NULL, "BackTab", */ /* KCTRL | KFIRST | 0x50, NULL, "Sh-North", */ KCTRL | KFIRST | 0x51, MSG_forw_unit, "Sh-East", /* KCTRL | KFIRST | 0x52, NULL, "Sh-South", */ KCTRL | KFIRST | 0x53, MSG_back_unit, "Sh-West", /* KCTRL | KFIRST | 0x54, NULL, "Sh-Home", */ KCTRL | KFIRST | 0x55, MSG_execute_macro, "Sh-Execute", /* KCTRL | KFIRST | 0x56, NULL, "Sh-Insert", */ KCTRL | KFIRST | 0x57, MSG_forw_del_unit, "Sh-Delete", KCTRL | KFIRST | 0x58, MSG_goto_bob, "Sh-PrevPage", KCTRL | KFIRST | 0x59, MSG_goto_eob, "Sh-NextPage", /* KCTRL | KFIRST | 0x5B, NULL, "Sh-Erase", */ /* KCTRL | KFIRST | 0x5C, NULL, "Sh-Tab", */ /* KCTRL | KFIRST | 0x5D, NULL, "Sh-BackTab", */ KCTRL | KFIRST | 0x60, MSG_abort, "Cancel", KMETA | KCTRL | KFIRST | 0x60, MSG_abort, "Cancel", KCTLX | KCTRL | KFIRST | 0x60, MSG_abort, "Ctl-X Cancel", KCTRL | KFIRST | 0x61, MSG_display_bindings, "Help", /* KCTRL | KFIRST | 0x62, NULL, "Glossary", */ KCTRL | KFIRST | 0x63, MSG_print, "Print", KCTRL | KFIRST | 0x71, MSG_help, "Sh-Help", /* KCTRL | KFIRST | 0x72, NULL, "Sh-Glossary", */ /* KCTRL | KFIRST | 0x73, NULL, "Sh-Print", */ 0, NULL, NULL }; #endif #if defined(MSDOS) || defined(OS2) KEY_NAME_ARRAY ibm_keys[] = { KCTLX | KFIRST | 0x3B, MSG_display_bindings, "F1", KCTLX | KFIRST | 0x3C, MSG_set_mark, "F2", KCTLX | KFIRST | 0x3D, MSG_forw_search, "F3", KCTLX | KFIRST | 0x3E, MSG_search_again, "F4", KCTLX | KFIRST | 0x3F, MSG_query_replace, "F5", KCTLX | KFIRST | 0x40, MSG_yank, "F6", KCTLX | KFIRST | 0x41, MSG_copy_region, "F7", KCTLX | KFIRST | 0x42, MSG_kill_region, "F8", KCTLX | KFIRST | 0x43, MSG_goto_line, "F9", KCTLX | KFIRST | 0x44, NULL, "F10", KCTLX | KFIRST | 0x85, NULL, "F11", KCTLX | KFIRST | 0x86, NULL, "F12", KCTLX | KFIRST | 0x54, MSG_help, "Sh-F1", KCTLX | KFIRST | 0x55, MSG_file_read, "Sh-F2", KCTLX | KFIRST | 0x56, MSG_file_save, "Sh-F3", KCTLX | KFIRST | 0x57, MSG_file_visit, "Sh-F4", KCTLX | KFIRST | 0x58, MSG_file_write, "Sh-F5", KCTLX | KFIRST | 0x59, MSG_flush_all, "Sh-F6", KCTLX | KFIRST | 0x5A, MSG_set_file_name, "Sh-F7", KCTLX | KFIRST | 0x5B, MSG_file_insert, "Sh-F8", KCTLX | KFIRST | 0x5C, MSG_exit_flush_all, "Sh-F9", KCTLX | KFIRST | 0x5D, MSG_quit, "Sh-F10", KCTLX | KFIRST | 0x87, NULL, "Sh-F11", KCTLX | KFIRST | 0x88, NULL, "Sh-F12", KCTLX | KFIRST | 0x5E, MSG_display_buffers, "Ctl-F1", KCTLX | KFIRST | 0x5F, MSG_use_buffer, "Ctl-F2", KCTLX | KFIRST | 0x60, MSG_kill_buffer, "Ctl-F3", KCTLX | KFIRST | 0x61, MSG_next_buff, "Ctl-F4", KCTLX | KFIRST | 0x62, MSG_prev_buff, "Ctl-F5", KCTLX | KFIRST | 0x63, MSG_yank_buffer, "Ctl-F6", KCTLX | KFIRST | 0x64, MSG_set_file_name, "Ctl-F7", KCTLX | KFIRST | 0x65, MSG_file_insert, "Ctl-F8", KCTLX | KFIRST | 0x66, MSG_exit_flush_all, "Ctl-F9", KCTLX | KFIRST | 0x67, MSG_quit, "Ctl-F10", KCTLX | KFIRST | 0x89, NULL, "Ctl-F11", KCTLX | KFIRST | 0x8A, NULL, "Ctl-F12", KCTLX | KFIRST | 0x68, NULL, "Alt-F1", KCTLX | KFIRST | 0x69, NULL, "Alt-F2", KCTLX | KFIRST | 0x6A, NULL, "Alt-F3", KCTLX | KFIRST | 0x6B, NULL, "Alt-F4", KCTLX | KFIRST | 0x6C, NULL, "Alt-F5", KCTLX | KFIRST | 0x6D, NULL, "Alt-F6", KCTLX | KFIRST | 0x6E, NULL, "Alt-F7", KCTLX | KFIRST | 0x6F, NULL, "Alt-F8", KCTLX | KFIRST | 0x70, NULL, "Alt-F9", KCTLX | KFIRST | 0x71, NULL, "Alt-F10", KCTLX | KFIRST | 0x8B, NULL, "Alt-F11", KCTLX | KFIRST | 0x8C, NULL, "Alt-F12", KCTLX | KFIRST | 0x48, MSG_back_line, "North", KCTLX | KFIRST | 0x4D, MSG_forw_char, "East", KCTLX | KFIRST | 0x50, MSG_forw_line, "South", KCTLX | KFIRST | 0x4B, MSG_back_char, "West", KCTLX | KFIRST | 0x8D, MSG_back_line, "Ctl-North", KCTLX | KFIRST | 0x74, MSG_forw_unit, "Ctl-East", KCTLX | KFIRST | 0x91, MSG_forw_line, "Ctl-South", KCTLX | KFIRST | 0x73, MSG_back_unit, "Ctl-West", KCTLX | KFIRST | 0x98, NULL, "Alt-North", KCTLX | KFIRST | 0x9D, NULL, "Alt-East", KCTLX | KFIRST | 0xA0, NULL, "Alt-South", KCTLX | KFIRST | 0x9B, NULL, "Alt-West", KCTLX | KFIRST | 0x49, MSG_back_page, "PageDown", KCTLX | KFIRST | 0x51, MSG_forw_page, "PageUp", KCTLX | KFIRST | 0x47, MSG_goto_bob, "Home", KCTLX | KFIRST | 0x4F, MSG_goto_eob, "End", KCTLX | KFIRST | 0x4C, NULL, "Center", KCTLX | KFIRST | 0x76, MSG_forw_window, "Ctl-PageDown", KCTLX | KFIRST | 0x84, MSG_back_window, "Ctl-PageUp", KCTLX | KFIRST | 0x77, MSG_goto_bob, "Ctl-Home", KCTLX | KFIRST | 0x75, MSG_goto_eob, "Ctl-End", KCTLX | KFIRST | 0x8F, NULL, "Ctl-Center", KCTLX | KFIRST | 0xA1, NULL, "Alt-PageDown", KCTLX | KFIRST | 0x99, NULL, "Alt-PageUp", KCTLX | KFIRST | 0x97, NULL, "Alt-Home", KCTLX | KFIRST | 0x9F, NULL, "Alt-End", KCTLX | KFIRST | 0x52, MSG_ins_toggle, "Insert", KCTLX | KFIRST | 0x53, MSG_forw_del_char, "Delete", KCTLX | KFIRST | 0x92, NULL, "Ctl-Insert", KCTLX | KFIRST | 0x93, NULL, "Ctl-Delete", KCTLX | KFIRST | 0xA2, NULL, "Alt-Insert", KCTLX | KFIRST | 0xA3, NULL, "Alt-Delete", KCTLX | KFIRST | 0x72, MSG_print, "Ctl-Print", KCTLX | KFIRST | 0x0F, NULL, "Sh-Tab", KCTLX | KFIRST | 0x94, NULL, "Ctl-Tab", KCTLX | KFIRST | 0xA5, NULL, "Alt-Tab", KCTLX | KFIRST | 0x95, NULL, "Ctrl-Num/", KCTLX | KFIRST | 0x96, NULL, "Ctrl-Num*", KCTLX | KFIRST | 0x8E, NULL, "Ctrl-Num-", KCTLX | KFIRST | 0x90, NULL, "Ctrl-Num+", KCTLX | KFIRST | 0xA4, NULL, "Alt-Num/", KCTLX | KFIRST | 0x37, NULL, "Alt-Num*", KCTLX | KFIRST | 0x4A, NULL, "Alt-Num-", KCTLX | KFIRST | 0x4E, NULL, "Alt-Num+", KCTLX | KFIRST | 0xA6, NULL, "Alt-NumEnter", KCTLX | KFIRST | 0x01, NULL, "Alt-Esc", KCTLX | KFIRST | 0x1C, NULL, "Alt-Enter", KCTLX | KFIRST | 0x0E, NULL, "Alt-Backspace", KCTLX | KFIRST | 0x1E, NULL, "Alt-A", KCTLX | KFIRST | 0x30, NULL, "Alt-B", KCTLX | KFIRST | 0x2E, NULL, "Alt-C", KCTLX | KFIRST | 0x20, NULL, "Alt-D", KCTLX | KFIRST | 0x12, NULL, "Alt-E", KCTLX | KFIRST | 0x21, NULL, "Alt-F", KCTLX | KFIRST | 0x22, NULL, "Alt-G", KCTLX | KFIRST | 0x23, NULL, "Alt-H", KCTLX | KFIRST | 0x17, NULL, "Alt-I", KCTLX | KFIRST | 0x24, NULL, "Alt-J", KCTLX | KFIRST | 0x25, NULL, "Alt-K", KCTLX | KFIRST | 0x26, NULL, "Alt-L", KCTLX | KFIRST | 0x32, NULL, "Alt-M", KCTLX | KFIRST | 0x31, NULL, "Alt-N", KCTLX | KFIRST | 0x18, NULL, "Alt-O", KCTLX | KFIRST | 0x19, NULL, "Alt-P", KCTLX | KFIRST | 0x10, NULL, "Alt-Q", KCTLX | KFIRST | 0x13, NULL, "Alt-R", KCTLX | KFIRST | 0x1F, NULL, "Alt-S", KCTLX | KFIRST | 0x14, NULL, "Alt-T", KCTLX | KFIRST | 0x16, NULL, "Alt-U", KCTLX | KFIRST | 0x2F, NULL, "Alt-V", KCTLX | KFIRST | 0x11, NULL, "Alt-W", KCTLX | KFIRST | 0x2D, NULL, "Alt-X", KCTLX | KFIRST | 0x15, NULL, "Alt-Y", KCTLX | KFIRST | 0x2C, NULL, "Alt-Z", KCTLX | KFIRST | 0x78, NULL, "Alt-1", KCTLX | KFIRST | 0x79, NULL, "Alt-2", KCTLX | KFIRST | 0x7A, NULL, "Alt-3", KCTLX | KFIRST | 0x7B, NULL, "Alt-4", KCTLX | KFIRST | 0x7C, NULL, "Alt-5", KCTLX | KFIRST | 0x7D, NULL, "Alt-6", KCTLX | KFIRST | 0x7E, NULL, "Alt-7", KCTLX | KFIRST | 0x7F, NULL, "Alt-8", KCTLX | KFIRST | 0x80, NULL, "Alt-9", KCTLX | KFIRST | 0x81, NULL, "Alt-0", 0, NULL, NULL }; #endif /* * Read in a key, doing the low level mapping * of ASCII code to 12 bit code. This level deals with * mapping the special keys into their spots in the C1 * control area. The C0 controls go right through, and * get remapped by "getkey". */ static int unkey = KRANDOM; /* jam - for ungetkey */ void ungetkey (k) int k; { unkey = k; } int getkbd () { register int c; if (unkey == KRANDOM) /* jam */ c = ttgetc (); else { c = unkey; unkey = KRANDOM; } if (c == SPECIAL) { c = ttgetc (); if ((c == 0xCD) || (c == 0xDD)) /* Backtab is meta */ return (METACH); return (c | KCTRL); } if (c == 0 || c == 0xE0) { c = ttgetc (); return (c | KFIRST | KCTLX); } return (c); } /* * Terminal specific keymap initialization. * Attach the special keys to the appropriate built * in functions. * As is the case of all the keymap routines, errors * are very fatal. */ void ttykeymapinit () { #ifdef MSDOS KEY_NAME_ARRAY *ptr; int i; char buf[NCOL]; if (wang_pc) ptr = wang_keys; if (ibm_pc) ptr = ibm_keys; if (!wang_pc && !ibm_pc) return; i = 0; while (ptr->key_code != 0) { if (ptr->func_name_str != NULL) keydup (ptr->key_code, ptr->func_name_str); ptr++; i++; } sprintf (buf, MSG_sp_key, i); writ_echo (buf); #endif #ifdef OS2 KEY_NAME_ARRAY *ptr; int i; char buf[NCOL]; ptr = ibm_keys; i = 0; while (ptr->key_code != 0) { if (ptr->func_name_str != NULL) keydup (ptr->key_code, ptr->func_name_str); ptr++; i++; } /* sprintf (buf, MSG_sp_key, i); writ_echo (buf); */ #endif } /* * Search key name array for given key code. * return pointer to key name. */ char * keystrings (key) int key; { #ifdef MSDOS KEY_NAME_ARRAY *ptr; if (wang_pc) ptr = wang_keys; if (ibm_pc) ptr = ibm_keys; if (!wang_pc && !ibm_pc) return (NULL); while (ptr->key_code != 0) { if (key == ptr->key_code) { return (ptr->key_name_str); } ptr++; } #endif #ifdef OS2 KEY_NAME_ARRAY *ptr = ibm_keys; while (ptr->key_code != 0) { if (key == ptr->key_code) { return (ptr->key_name_str); } ptr++; } #endif return (NULL); } beav-140/wangpc.c0000644000175000001440000000605405667134707013703 0ustar samusers00000000000000#include "def.h" #if MSDOS #include "dos.h" typedef struct SCREENINFO { unsigned char state; unsigned char scanoff; unsigned short bufseg; unsigned char colors; unsigned char row; unsigned char col; unsigned char attr; unsigned char auxmod; unsigned char auxmod2; } SCREENINFO; typedef struct SYSCONFIG { unsigned short version; unsigned short memsize; unsigned short reserved[2]; unsigned short screen_count; unsigned short screens[4]; } SYSCONFIG; #define SENDCHAR 6 #define SENDLINE 0x0d #define BIOS 0x88 #define GETSYSCON 1 bool wang_pc = FALSE; bool ibm_pc = FALSE; bool mem_map = FALSE; void is_wang () { union REGS inregs, outregs; struct SREGS segregs; unsigned char *memptr; unsigned char c; int i; static char wang_id[] = { "WANG"}; static char ret_str[6]; char *chr_ptr; chr_ptr = ret_str; /* test for Wang PC */ memptr = (unsigned char *) 0xFC003FC2L; wang_pc = TRUE; for (i = 0; (i < 4 && wang_pc); i++) { if (*memptr != wang_id[i]) wang_pc = FALSE; memptr++; } if (wang_pc) { mem_map = TRUE; ret_str[0] = 0xFF; /* set to known value */ mem_map = TRUE; inregs.h.al = 0x02; inregs.h.ah = 0x44; inregs.x.bx = 0; inregs.x.cx = 1; inregs.x.dx = FP_OFF (chr_ptr); segregs.ds = FP_SEG (chr_ptr); int86x (0x21, &inregs, &outregs, &segregs); if (ret_str[0] == 0x11) { ibm_pc = TRUE; return; } ibm_pc = FALSE; return; } /* Must be an IBM or clone */ memptr = (unsigned char *) 0xF000FFFEL; c = *memptr; switch (c) { case 0xFC: /* IBM AT or clone */ case 0xFD: /* IBM PC Jr */ case 0xFE: /* IBM XT or clone */ case 0xFF: /* IBM PC or clone */ mem_map = TRUE; ibm_pc = TRUE; return; } } int getsysconfig (outregs, segregs) union REGS *outregs; struct SREGS *segregs; { union REGS inregs; inregs.h.al = GETSYSCON; int86x (BIOS, &inregs, outregs, segregs); } char getscreenstate () { struct SREGS segregs; union REGS outregs; struct SYSCONFIG *config; struct SCREENINFO *screeninfo; unsigned short *shortptr; unsigned int screen_count; getsysconfig (&outregs, &segregs); /* set pointer to force register info into a long pointer. */ shortptr = (unsigned short *) &config; /* Offset is first, it comes back in BX */ *shortptr = (unsigned short) outregs.x.bx; shortptr++; /* segment is in ES */ *shortptr = (unsigned short) segregs.es; /* Now, the config pointer should be set to the config table. */ /* printf("Version = %04x \n",config->version); printf("Memsize = %04x \n",config->memsize); printf("Screens = %04x \n",config->screen_count); */ screen_count = config->screen_count; while (screen_count) { shortptr = (unsigned short *) &screeninfo; *shortptr = (unsigned short) config->screens[screen_count - 1]; shortptr++; *shortptr = (unsigned short) segregs.es; if (screeninfo->state & 0x80) break; screen_count--; } return (screeninfo->state); } #endif beav-140/window.c0000644000175000001440000002752005667134707013734 0ustar samusers00000000000000/* * Window handling. */ #include "def.h" bool mvupwind (); bool shrinkwind (); extern char MSG_no_splt[]; extern char MSG_cnt_al_w[]; extern char MSG_one_w[]; extern char MSG_imp_chg[]; extern char MSG_scrn_rows[]; extern char MSG_bad_num[]; /* * Reposition the window so as to center on the dot. */ bool reposition () { long l_val; l_val = DOT_POS (curwp) - (curwp->w_ntrows * R_BYTES (curwp) / 2L); move_ptr (curwp, l_val, FALSE, TRUE, FALSE); curwp->w_flag |= WFHARD; return (TRUE); } /* * The command make the next * window (next => down the screen) * the current window. There are no real * errors, although the command does * nothing if there is only 1 window on * the screen. */ bool nextwind () { register WINDOW *wp; if ((wp = curwp->w_wndp) == NULL) wp = wheadp; curwp = wp; curbp = wp->w_bufp; return (TRUE); } /* * This command makes the previous * window (previous => up the screen) the * current window. There arn't any errors, * although the command does not do a lot * if there is 1 window. */ bool prevwind () { register WINDOW *wp1; register WINDOW *wp2; wp1 = wheadp; wp2 = curwp; if (wp1 == wp2) wp2 = NULL; while (wp1->w_wndp != wp2) wp1 = wp1->w_wndp; curwp = wp1; curbp = wp1->w_bufp; return (TRUE); } /* * This command moves the current * window down by "arg" lines. Recompute * the top line in the window. The move up and * move down code is almost completely the same; * most of the work has to do with reframing the * window, and picking a new dot. We share the * code by having "move down" just be an interface * to "move up". */ bool mvdnwind (f, n, k) int f, n, k; { return (mvupwind (f, -n, KRANDOM)); } /* * Move the current window up by "arg" * lines. Recompute the new top line of the window. * Look to see if "." is still on the screen. If it is, * you win. If it isn't, then move "." to center it * in the new framing of the window (this command does * not really move "."; it moves the frame). */ bool mvupwind (f, n, k) int f, n, k; { A32 l_val, l_bytes; l_bytes = (A32) R_BYTES (curwp); /* number of bytes in a row */ l_val = n * l_bytes; /* number of bytes to move */ move_ptr (curwp, l_val, FALSE, TRUE, TRUE); /* move window */ /* check that dot is in window */ while (DOT_POS (curwp) < WIND_POS (curwp)) { /* dot is before the first window line */ move_ptr (curwp, l_bytes, TRUE, TRUE, TRUE); } while (DOT_POS (curwp) >= ((l_bytes * curwp->w_ntrows) + WIND_POS (curwp))) { /* dot is after the last window line */ move_ptr (curwp, -l_bytes, TRUE, TRUE, TRUE); } curwp->w_flag |= WFHARD; return (TRUE); } /* * This command makes the current * window the only window on the screen. * Try to set the framing * so that "." does not have to move on * the display. Some care has to be taken * to keep the values of dot and mark * in the buffer structures right if the * distruction of a window makes a buffer * become undisplayed. */ bool onlywind () { register WINDOW *wp; register LINE *lp; register int i; while (wheadp != curwp) { wp = wheadp; wheadp = wp->w_wndp; if (--wp->w_bufp->b_nwnd == 0) { wp->w_bufp->b_dotp = wp->w_dotp; wp->w_bufp->b_doto = wp->w_doto; wp->w_bufp->b_markp = wp->w_markp; wp->w_bufp->b_marko = wp->w_marko; } free ((char *) wp); } while (curwp->w_wndp != NULL) { wp = curwp->w_wndp; curwp->w_wndp = wp->w_wndp; if (--wp->w_bufp->b_nwnd == 0) { wp->w_bufp->b_dotp = wp->w_dotp; wp->w_bufp->b_doto = wp->w_doto; wp->w_bufp->b_markp = wp->w_markp; wp->w_bufp->b_marko = wp->w_marko; } free ((char *) wp); } lp = curwp->w_linep; i = curwp->w_toprow; while (i != 0 && lback (lp) != curbp->b_linep) { --i; lp = lback (lp); } curwp->w_toprow = 0; curwp->w_ntrows = nrow - 2; /* 2 = mode, echo. */ curwp->w_linep = lp; curwp->w_flag |= WFMODE | WFHARD; return (TRUE); } /* * Delete the current window, placing its space in the window above, * or, if it is the top window, the window below. Bound to C-X 0. */ bool delwind () { register WINDOW *wp; /* window to recieve deleted space */ register WINDOW *lwp; /* ptr window before curwp */ register int target; /* target line to search for */ /* if there is only one window, don't delete it */ if (wheadp->w_wndp == NULL) { return (FALSE); } /* find window before curwp in linked list */ wp = wheadp; lwp = NULL; while (wp != NULL) { if (wp == curwp) break; lwp = wp; wp = wp->w_wndp; } /* find recieving window and give up our space */ wp = wheadp; if (curwp->w_toprow == 0) { /* find the next window down */ target = curwp->w_ntrows + 1; while (wp != NULL) { if (wp->w_toprow == target) break; wp = wp->w_wndp; } if (wp == NULL) return (FALSE); wp->w_toprow = 0; wp->w_ntrows += target; } else { /* find the next window up */ target = curwp->w_toprow - 1; while (wp != NULL) { if ((wp->w_toprow + wp->w_ntrows) == target) break; wp = wp->w_wndp; } if (wp == NULL) return (FALSE); wp->w_ntrows += 1 + curwp->w_ntrows; } /* get rid of the current window */ if (--curwp->w_bufp->b_nwnd == 0) { curwp->w_bufp->b_dotp = curwp->w_dotp; curwp->w_bufp->b_doto = curwp->w_doto; curwp->w_bufp->b_markp = curwp->w_markp; curwp->w_bufp->b_marko = curwp->w_marko; } if (lwp == NULL) wheadp = curwp->w_wndp; else lwp->w_wndp = curwp->w_wndp; free ((char *) curwp); curwp = wp; wp->w_flag |= WFMODE | WFHARD; curbp = wp->w_bufp; return (TRUE); } /* * Split the current window. A window * smaller than 3 lines cannot be split. * The only other error that is possible is * a "malloc" failure allocating the structure * for the new window. */ bool splitwind () { register WINDOW *wp; register int ntru; register int ntrl; register int ntrd; register WINDOW *wp1; register WINDOW *wp2; char buf[NCOL], buf1[NCOL]; if (curwp->w_ntrows < MIN_WIN_ROWS) { sprintf (buf1, MSG_no_splt, R_BYTE_FMT (curwp)); sprintf (buf, buf1, curwp->w_ntrows); writ_echo (buf); return (FALSE); } if ((wp = (WINDOW *) malloc (sizeof (WINDOW))) == NULL) { err_echo (MSG_cnt_al_w); return (FALSE); } ++curbp->b_nwnd; /* Displayed twice. */ wp->w_bufp = curbp; wp->w_dotp = curwp->w_dotp; wp->w_doto = curwp->w_doto; wp->w_unit_offset = curwp->w_unit_offset; wp->w_markp = curwp->w_markp; wp->w_marko = curwp->w_marko; wp->w_flag = 0; wp->w_disp_shift = curwp->w_disp_shift; wp->w_intel_mode = curwp->w_intel_mode; wp->w_fmt_ptr = curwp->w_fmt_ptr; ntru = (curwp->w_ntrows - 1) / 2; /* Upper size */ ntrl = (curwp->w_ntrows - 1) - ntru; /* Lower size */ curwp->w_ntrows = ntru; wp->w_wndp = curwp->w_wndp; curwp->w_wndp = wp; wp->w_toprow = curwp->w_toprow + ntru + 1; wp->w_ntrows = ntrl; wind_on_dot (curwp); /* put window on the dot */ wp->w_loff = curwp->w_loff; /* do the same for the new window */ wp->w_linep = curwp->w_linep; curwp->w_flag |= WFMODE | WFHARD; wp->w_flag |= WFMODE | WFHARD; return (TRUE); } /* * Enlarge the current window. * Find the window that loses space. Make * sure it is big enough. If so, hack the window * descriptions, and ask redisplay to do all the * hard work. You don't just set "force reframe" * because dot would move. */ bool enlargewind (f, n, k) int f, n, k; { register WINDOW *adjwp; register LINE *lp; register int i; if (n < 0) return (shrinkwind (f, -n, KRANDOM)); if (wheadp->w_wndp == NULL) { writ_echo (MSG_one_w); return (FALSE); } if ((adjwp = curwp->w_wndp) == NULL) { adjwp = wheadp; while (adjwp->w_wndp != curwp) adjwp = adjwp->w_wndp; } if (adjwp->w_ntrows <= n) { writ_echo (MSG_imp_chg); return (FALSE); } if (curwp->w_wndp == adjwp) { /* Shrink below. */ lp = adjwp->w_linep; for (i = 0; i < n && lp != adjwp->w_bufp->b_linep; ++i) lp = lforw (lp); adjwp->w_linep = lp; adjwp->w_toprow += n; } else { /* Shrink above. */ lp = curwp->w_linep; for (i = 0; i < n && lback (lp) != curbp->b_linep; ++i) lp = lback (lp); curwp->w_linep = lp; curwp->w_toprow -= n; } curwp->w_ntrows += n; adjwp->w_ntrows -= n; curwp->w_flag |= WFMODE | WFHARD; adjwp->w_flag |= WFMODE | WFHARD; return (TRUE); } /* * Shrink the current window. * Find the window that gains space. Hack at * the window descriptions. Ask the redisplay to * do all the hard work. */ bool shrinkwind (f, n, k) int f, n, k; { register WINDOW *adjwp; register LINE *lp; register int i; if (n < 0) return (enlargewind (f, -n, KRANDOM)); if (wheadp->w_wndp == NULL) { writ_echo (MSG_one_w); return (FALSE); } if ((adjwp = curwp->w_wndp) == NULL) { adjwp = wheadp; while (adjwp->w_wndp != curwp) adjwp = adjwp->w_wndp; } if (curwp->w_ntrows <= n) { writ_echo (MSG_imp_chg); return (FALSE); } if (curwp->w_wndp == adjwp) { /* Grow below. */ lp = adjwp->w_linep; for (i = 0; i < n && lback (lp) != adjwp->w_bufp->b_linep; ++i) lp = lback (lp); adjwp->w_linep = lp; adjwp->w_toprow -= n; } else { /* Grow above. */ lp = curwp->w_linep; for (i = 0; i < n && lp != curbp->b_linep; ++i) lp = lforw (lp); curwp->w_linep = lp; curwp->w_toprow += n; } curwp->w_ntrows -= n; adjwp->w_ntrows += n; curwp->w_flag |= WFMODE | WFHARD; adjwp->w_flag |= WFMODE | WFHARD; return (TRUE); } /* * Pick a window for a pop-up. * Split the screen if there is only * one window. Pick the uppermost window that * isn't the current window. An LRU algorithm * might be better. Return a pointer, or * NULL on error. */ WINDOW * wpopup () { register WINDOW *wp; if (wheadp->w_wndp == NULL && splitwind () == FALSE) return (NULL); wp = wheadp; /* Find window to use */ while (wp != NULL && wp == curwp) wp = wp->w_wndp; return (wp); } /* * Refresh the display. * In the normal case the * call to "update" in "main.c" refreshes the screen, * and all of the windows need not be recomputed. */ bool refresh () { sgarbf = TRUE; return (TRUE); } /* pvr * Set the number of rows on the screen. * This sets the nrow value and fixes up the windows * to account for the new size. */ bool screen_rows (f, n, k) int f, n, k; { int new_rows; register int s; char buf[80]; WINDOW *wp, *cur_wp_sav; cur_wp_sav = curwp; new_rows = nrow; /* default it if sscanf reads nothing */ sprintf (buf, "%s [%d] ", MSG_scrn_rows, nrow); if (f == FALSE) { if ((s = ereply (buf, buf, sizeof (buf), 0) != TRUE)) return (s); sscanf (buf, "%d", &new_rows); } else new_rows = n; if (new_rows <= MIN_WIN_ROWS) { writ_echo (MSG_bad_num); return (FALSE); } ttmove (0, 0); tteeop (); refresh (); /* set new nrow value */ nrow = new_rows; while (TRUE) { /* find last window */ for (wp = wheadp; wp->w_wndp; wp = wp->w_wndp) wp->w_flag |= WFHARD; /* update all windows */ wp->w_flag |= WFHARD; /* update last windows */ /* if no part of window can fit, kill it */ if ((wp->w_toprow + MIN_WIN_ROWS) >= new_rows) { /* don't kill last window */ if (wp == wheadp) { nrow = MIN_WIN_ROWS + 2; /* set min size */ wp->w_ntrows = MIN_WIN_ROWS; wind_on_dot (wp); break; } curwp = wp; curbp = wp->w_bufp; delwind (); } else { /* adjust window to fit */ wp->w_ntrows = new_rows - wp->w_toprow - 2; wind_on_dot (wp); break; } } /* free up old screen memory */ vtfree (); /* recreate scerrn buffers */ vtinit (); eerase (); /* clean up prompt line */ return (TRUE); } beav-140/word.c0000644000175000001440000000544405667134707013401 0ustar samusers00000000000000/* * Word mode commands. * The routines in this file * implement commands that work unit at * a time. There are all sorts of unit mode * commands. If I do any sentence and/or paragraph * mode commands, they are likely to be put in * this file. */ #include "def.h" extern BUFFER sav_buf; char forwunit (); /* * Move the cursor backward by * "n" units. All of the details of motion * are performed by the "backchar" and "forwchar" * routines. Error if you try to move beyond * the buffers. */ char backunit (f, n, k) int f, n, k; { char ret; if (n < 0) return (forwunit (f, -n, KRANDOM)); curwp->w_unit_offset = 0; while (n--) { ret = move_ptr (curwp, -(long) R_B_PER_U (curwp), TRUE, TRUE, TRUE); } wind_on_dot (curwp); curwp->w_flag |= WFMODE; /* update mode line */ return (ret); } /* * Move the cursor forward by * the specified number of units. All of the * motion is done by "forwchar". Error if you * try and move beyond the buffer's end. */ char forwunit (f, n, k) int f, n, k; { if (n < 0) return (backunit (f, -n, KRANDOM)); curwp->w_unit_offset = 0; while (n--) { move_ptr (curwp, (long) R_B_PER_U (curwp), TRUE, TRUE, TRUE); } wind_on_dot (curwp); curwp->w_flag |= WFMODE; /* update mode line */ return (TRUE); } /* * Kill forward by "n" units. The rules for final * status are now different. It is not considered an error * to delete fewer units than you asked. This lets you say * "kill lots of units" and have the command stop in a reasonable * way when it hits the end of the buffer. */ bool delfunit (f, n, k) int f, n, k; { if (n < 0) return (FALSE); if ((lastflag & CFKILL) == 0) /* Purge kill buffer. */ bclear (&sav_buf); thisflag |= CFKILL; while (n--) { ldelete ((A32) (R_B_PER_U (curwp)), TRUE); } curwp->w_flag |= WFHARD; curwp->w_unit_offset = 0; return (TRUE); } /* * Kill backwards by "n" units. The rules * for success and failure are now different, to prevent * strange behavior at the start of the buffer. The command * only fails if something goes wrong with the actual delete * of the characters. It is successful even if no characters * are deleted, or if you say delete 5 units, and there are * only 4 units left. I considered making the first call * to "backchar" special, but decided that that would just * be wierd. Normally this is bound to "M-Rubout" and * to "M-Backspace". */ bool delbunit (f, n, k) int f, n, k; { int size; if (n < 0) return (FALSE); if ((lastflag & CFKILL) == 0) /* Purge kill buffer. */ bclear (&sav_buf); thisflag |= CFKILL; size = R_B_PER_U (curwp); while (n--) { if (move_ptr (curwp, -((long) size), TRUE, TRUE, TRUE)) ldelete ((A32) size, TRUE); } curwp->w_flag |= WFHARD; return (TRUE); }