Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!utgpu!water!watmath!clyde!rutgers!husc6!sri-unix!ctnews!pyramid!uccba!hal!ncoast!allbery
From: allbery@ncoast.UUCP
Newsgroups: comp.sources.misc
Subject: memacs 3.8i 5 of 11
Message-ID: <2660@ncoast.UUCP>
Date: Wed, 17-Jun-87 22:23:32 EDT
Article-I.D.: ncoast.2660
Posted: Wed Jun 17 22:23:32 1987
Date-Received: Sat, 20-Jun-87 02:23:33 EDT
Sender: allbery@ncoast.UUCP
Lines: 2202
Approved: allbery@ncoast.UUCP
:
#!/bin/sh
# shar+ created from directory /usr2/davidsen/emacs38i
# 13:42 on Thu Jun 11, 1987 by davidsen
echo 'x - hp110.c (text)'
sed << 'E!O!F' 's/^X//' > hp110.c
X/*
X * HP110: Hewlett Packard 110 Screen Driver
X */
X
X#define termdef 1 /* don't define "term" external */
X
X#include
X#include "estruct.h"
X#include "edef.h"
X
X#if HP110
X
X#define NROW 16 /* Screen size. */
X#define NCOL 80 /* Edit if you want to. */
X#define NPAUSE 100 /* # times thru update to pause */
X#define MARGIN 8 /* size of minimim margin and */
X#define SCRSIZ 64 /* scroll size for extended lines */
X#define BEL 0x07 /* BEL character. */
X#define ESC 0x1B /* ESC character. */
X
Xextern int ttopen(); /* Forward references. */
Xextern int ttgetc();
Xextern int ttputc();
Xextern int ttflush();
Xextern int ttclose();
Xextern int h110move();
Xextern int h110eeol();
Xextern int h110eeop();
Xextern int h110beep();
Xextern int h110open();
Xextern int h110rev();
Xextern int h110cres();
Xextern int h110close();
Xextern int h110kopen();
Xextern int h110kclose();
X
X#if COLOR
Xextern int h110fcol();
Xextern int h110bcol();
X
Xint cfcolor = -1; /* current forground color */
Xint cbcolor = -1; /* current background color */
X#endif
X
X/*
X * Standard terminal interface dispatch table. Most of the fields point into
X * "termio" code.
X */
XTERM term = {
X NROW-1,
X NROW-1,
X NCOL,
X NCOL,
X MARGIN,
X SCRSIZ,
X NPAUSE,
X h110open,
X h110close,
X h110kopen,
X h110kclose,
X ttgetc,
X ttputc,
X ttflush,
X h110move,
X h110eeol,
X h110eeop,
X h110beep,
X h110rev,
X h110cres
X#if COLOR
X , h110fcol,
X h110bcol
X#endif
X};
X
X#if COLOR
Xh110fcol(color) /* set the current output color */
X
Xint color; /* color to set */
X
X{
X if (color == cfcolor)
X return;
X ttputc(ESC);
X ttputc('[');
X h110parm(color+30);
X ttputc('m');
X cfcolor = color;
X}
X
Xh110bcol(color) /* set the current background color */
X
Xint color; /* color to set */
X
X{
X if (color == cbcolor)
X return;
X ttputc(ESC);
X ttputc('[');
X h110parm(color+40);
X ttputc('m');
X cbcolor = color;
X}
X#endif
X
Xh110move(row, col)
X{
X ttputc(ESC);
X ttputc('[');
X h110parm(row+1);
X ttputc(';');
X h110parm(col+1);
X ttputc('H');
X}
X
Xh110eeol()
X{
X ttputc(ESC);
X ttputc('[');
X ttputc('0');
X ttputc('K');
X}
X
Xh110eeop()
X{
X#if COLOR
X h110fcol(gfcolor);
X h110bcol(gbcolor);
X#endif
X ttputc(ESC);
X ttputc('[');
X ttputc('0');
X ttputc('J');
X}
X
Xh110rev(state) /* change reverse video state */
X
Xint state; /* TRUE = reverse, FALSE = normal */
X
X{
X#if COLOR
X int ftmp, btmp; /* temporaries for colors */
X#endif
X
X ttputc(ESC);
X ttputc('[');
X ttputc(state ? '7': '0');
X ttputc('m');
X#if COLOR
X if (state == FALSE) {
X ftmp = cfcolor;
X btmp = cbcolor;
X cfcolor = -1;
X cbcolor = -1;
X h110fcol(ftmp);
X h110bcol(btmp);
X }
X#endif
X}
X
Xh110cres() /* change screen resolution */
X
X{
X return(TRUE);
X}
X
Xspal() /* change pallette register */
X
X{
X /* not here */
X}
X
Xh110beep()
X{
X ttputc(BEL);
X ttflush();
X}
X
Xh110parm(n)
Xregister int n;
X{
X register int q,r;
X
X q = n/10;
X if (q != 0) {
X r = q/10;
X if (r != 0) {
X ttputc((r%10)+'0');
X }
X ttputc((q%10) + '0');
X }
X ttputc((n%10) + '0');
X}
X
Xh110open()
X{
X strcpy(sres, "15LINE");
X revexist = TRUE;
X ttopen();
X}
X
Xh110close()
X
X{
X#if COLOR
X h110fcol(7);
X h110bcol(0);
X#endif
X ttclose();
X}
X
Xh110kopen()
X
X{
X}
X
Xh110kclose()
X
X{
X}
X
X#if FLABEL
Xfnclabel(f, n) /* label a function key */
X
Xint f,n; /* default flag, numeric argument [unused] */
X
X{
X /* on machines with no function keys...don't bother */
X return(TRUE);
X}
X#endif
X#else
Xh110hello()
X{
X}
X#endif
E!O!F
newsize=`wc -c < hp110.c`
if [ $newsize -ne 3750 ]
then echo "File hp110.c was $newsize bytes, 3750 expected"
fi
echo 'x - hp150.c (text)'
sed << 'E!O!F' 's/^X//' > hp150.c
X/*
X * The routines in this file provide support for HP150 screens
X * and routines to access the Keyboard through KEYCODE mode.
X * It compiles into nothing if not an HP150 screen device.
X * added by Daniel Lawrence
X */
X
X#define termdef 1 /* don't define "term" external */
X
X#include
X#include "estruct.h"
X#include "edef.h"
X
X#if HP150
X
X#define NROW 24 /* Screen size. */
X#define NCOL 80 /* Edit if you want to. */
X#define MARGIN 8 /* size of minimim margin and */
X#define SCRSIZ 64 /* scroll size for extended lines */
X#define NPAUSE 15 /* # times thru update to pause */
X#define BEL 0x07 /* BEL character. */
X#define ESC 0x1B /* ESC character. */
X
Xextern int openhp(); /* Forward references. */
Xextern int ttgetc();
Xextern int ttputc();
Xextern int ttflush();
Xextern int hpflush();
Xextern int closehp();
Xextern int hp15kopen();
Xextern int hp15kclose();
Xextern int hp15move();
Xextern int hp15eeol();
Xextern int hp15eeop();
Xextern int hp15beep();
Xextern int gethpkey();
Xextern int hp15rev();
Xextern int hp15cres();
X#if COLOR
Xextern int hp15fcol();
Xextern int hp15bcol();
X#endif
X
X/* weird to ascii translation table */
X
Xchar trans[][2] = {
X 0x24, 9, /* tab */
X 0x25, 13, /* ret */
X 0x27, 8, /* backspace */
X 0x30, 48, /* zero */
X 0x31, 49, /* one */
X 0x32, 50, /* two */
X 0x33, 51, /* three */
X 0x34, 52, /* four */
X 0x35, 53, /* five */
X 0x36, 54, /* six */
X 0x37, 55, /* seven */
X 0x38, 56, /* eight */
X 0x39, 57, /* nine */
X 0x50, 13, /* enter */
X 0x54, 27, /* break -> ESC */
X 0x55, 27, /* esc */
X 0x58, 24, /* stop -> ^X */
X 0x70, 45, /* N-minus */
X 0x71, 42, /* N-asterisk */
X 0x72, 43, /* N-plus */
X 0x73, 47, /* N-slash */
X 0x74, 44, /* N-comma */
X 0x75, 13, /* N-enter */
X 0x76, 9, /* N-tab */
X 0x77, 46 /* N-period */
X};
X
X#define NTRANS sizeof(trans) / 2
X
Xunion REGS r; /* register set for bios and dos (AGIOS) calls */
Xint capslock = 0; /* caps lock flag */
X
X/*
X * Standard terminal interface dispatch table. Most of the fields point into
X * "termio" code.
X */
XTERM term = {
X NROW-1,
X NROW-1,
X NCOL,
X NCOL,
X MARGIN,
X SCRSIZ,
X NPAUSE,
X openhp,
X closehp,
X hp15kopen,
X hp15kclose,
X gethpkey,
X ttputc,
X hpflush,
X hp15move,
X hp15eeol,
X hp15eeop,
X hp15beep,
X hp15rev,
X hp15cres
X#if COLOR
X , hp15fcol,
X hp15bcol
X#endif
X};
X
Xhp15move(row, col)
X{
X ttputc(ESC);
X ttputc('&');
X ttputc('a');
X hp15parm(col);
X ttputc('c');
X hp15parm(row);
X ttputc('R');
X}
X
Xhpflush()
X
X{
X
X}
X
Xhp15eeol()
X{
X ttputc(ESC);
X ttputc('K');
X}
X
Xhp15eeop()
X{
X ttputc(ESC);
X ttputc('J');
X}
X
Xhp15rev(status) /* change the reverse video status */
X
Xint status; /* TRUE = on, FALSE = off */
X
X{
X ttputc(ESC);
X ttputc('&');
X ttputc('d');
X ttputc((status != FALSE) ? 'B': '@');
X}
X
Xhp15cres() /* change screen resolution */
X
X{
X return(TRUE);
X}
X
Xspal() /* change pallette register */
X
X{
X /* not here */
X}
X
Xhp15beep()
X{
X ttputc(BEL);
X ttflush();
X}
X
Xhp15parm(n)
Xregister int n;
X{
X register int q;
X
X q = n/10;
X if (q != 0)
X hp15parm(q);
X ttputc((n%10) + '0');
X}
X
X#if COLOR
Xhp15fcol() /* we really can't do colors here, so just ignore it */
X{
X}
X
Xhp15bcol() /* we really can't do colors here, so just ignore it */
X{
X}
X#endif
X
Xgethpkey() /* get a key from the HP keyboard while in keycode mode */
X
X{
X static int keepflag = 0; /* kept ahead char flag */
X static int keepchar = 0; /* kept ehead flag */
X int c;
X int devid; /* device ID */
X int ctype; /* type of character gotten */
X int shiftb; /* state of shift keys */
X int i;
X
X /* if we are in an extended char sequence, finish it */
X if (keepflag != 0) {
X keepflag = 0;
X return(keepchar);
X }
X
X /* grab the next 4 char sequence */
Xnext: shiftb = ttgetc();
X devid = ttgetc();
X c = ttgetc();
X ttgetc(); /* skip null byte */
X
X /* make sure we are from the keyboard */
X if (devid != 192)
X goto next;
X
X /* if normal ascii, return it */
X if ((shiftb & 0x80) == 0) {
X if (capslock && c >= 'a' && c <= 'z')
X c -= 32;
X return(c);
X }
X
X /* check specifically for the caps lock key */
X if (c == 0x56) {
X capslock = ~capslock;
X goto next;
X }
X
X /* check to see if it needs translation */
X for (i=0; i < NTRANS; i++)
X if (trans[i][0] == c)
X return((int)trans[i][1]);
X
X /* other wise, shove it in the keep char and return the leadin code */
X keepchar = c;
X keepflag = 1;
X return(0);
X}
X
Xopenhp() /* open the HP150 screen for input */
X
X{
X strcpy(sres, "NORMAL");
X revexist = TRUE;
X}
X
Xclosehp() /* close the HP150 screen for input */
X
X{
X}
X
Xhp15kopen() /* open the HP150 keyboard for input */
X
X{
X /* define key charectoristics with AGIOS call (0, 40) */
X defkey();
X
X /* Turn on RAW mode with MSDOS call 44h */
X rawon();
X
X /* Turn off Control-C checking MS-DOS 33h */
X ckeyoff();
X
X /* Turn on keycode mode with AGIOS call (0,43) */
X keycon();
X
X /* display the application softkey labels */
X dsplbls();
X}
X
Xhp15kclose() /* close the HP150 keyboard for input */
X
X{
X /* define key charectoristics with AGIOS call (0, 40) */
X undefkey();
X
X /* Turn off RAW mode with MSDOS call 44h */
X rawoff();
X
X /* Turn on Control-C checking MS-DOS 33h */
X ckeyon();
X
X /* Turn off keycode mode with AGIOS call (0,43) */
X keycoff();
X}
X
Xrawon() /* put the HP150 keyboard into RAW mode */
X
X{
X /* get the IO control info */
X
X r.x.ax = 0x4400; /* IO ctrl get device information */
X r.x.bx = 0x0001; /* File handle; 1 for console */
X intdos(&r, &r); /* go fer it */
X
X r.h.dh = 0; /* clear high byte for put */
X r.h.dl |= 0x20; /* set raw bit */
X
X /* and put it back */
X
X r.x.ax = 0x4401; /* IO ctrl put device information */
X r.x.bx = 0x0001; /* File handle; 1 for console */
X intdos(&r, &r); /* go fer it */
X}
X
Xrawoff() /* put the HP150 keyboard into COOKED mode */
X
X{
X /* get the IO control info */
X
X r.x.ax = 0x4400; /* IO ctrl get device information */
X r.x.bx = 0x0001; /* File handle; 1 for console */
X intdos(&r, &r); /* go fer it */
X
X r.h.dh = 0; /* clear high byte for put */
X r.h.dl &= 0xdf; /* set raw bit */
X
X /* and put it back */
X
X r.x.ax = 0x4401; /* IO ctrl put device information */
X r.x.bx = 0x0001; /* File handle; 1 for console */
X intdos(&r, &r); /* go fer it */
X}
X
X
Xckeyoff() /* turn control-C trapping off */
X
X{
X r.h.ah = 0x33; /* ctrl-break check */
X r.h.al = 1; /* set the state of the ctrl-break check */
X r.h.dl = 0; /* turn it off */
X intdos(&r, &r);
X}
X
Xckeyon() /* turn control-C trapping on */
X
X{
X r.h.ah = 0x33; /* ctrl-break check */
X r.h.al = 1; /* set the state of the ctrl-break check */
X r.h.dl = 1; /* turn it on */
X intdos(&r, &r);
X}
X
Xagios(buf, len) /* perform an AGIOS call */
X
Xchar *buf; /* sequence of bytes in command */
Xint len; /* length of command in bytes */
X
X{
X r.x.ax = 0x4403; /* I/O ctrl write */
X r.x.bx = 1; /* console handle */
X r.x.cx = len; /* buffer length */
X r.x.dx = (unsigned)buf; /* buffer address */
X return(intdos(&r, &r)); /* do it */
X}
X
Xkeycon() /* turn keycode mode on */
X
X{
X static char cmd[] = {43, 0, 1};
X
X return(agios(&cmd[0], 3));
X}
X
Xkeycoff() /* turn keycode mode off */
X
X{
X static char cmd[] = {43, 0, 0};
X
X return(agios(&cmd[0], 3));
X}
X
Xdefkey() /* change all special keys to intercept mode */
X
X{
X static char cmd[] = {40, 0, 2, 0, 0xfe, 0};
X
X return(agios(&cmd[0], 6));
X}
X
Xundefkey() /* change all special keys to intercept mode */
X
X{
X static char cmd[] = {40, 0, 0, 0, 0xfe, 0};
X
X return(agios(&cmd[0], 6));
X}
X
Xdsplbls() /* display the application softkey labels on the screen */
X
X{
X static char cmd[] = {11, 0};
X
X return(agios(&cmd[0], 2));
X}
X
X#if FLABEL
Xfnclabel(f, n) /* label a function key */
X
Xint f,n; /* default flag, numeric argument */
X
X{
X register int status; /* return status */
X register int i; /* loop index */
X char lbl[17]; /* returned label contents */
X /* AGIOS command buffer */
X static char cmd[] = {8, 0, 1, 0, 7, 7, 7, 7, 10, 0, 10, 0};
X /* code key# ptr to top bottom
X label string attribute */
X union { /* union to cast ptr into AGIOS arg string */
X char *ptr; /* pointer to arg string */
X char cstr[4];
X } ptru;
X
X /* must have a numeric argument */
X if (f == FALSE) {
X mlwrite("%Need function key number");
X return(FALSE);
X }
X
X /* and it must be a legal key number */
X if (n < 1 || n > 8) {
X mlwrite("%Function key number out of range");
X return(FALSE);
X }
X
X /* get the string to send */
X status = mlreply("Label contents: ", &lbl[0], 17);
X if (status != TRUE)
X return(status);
X
X /* pad the label out */
X for (i=0; i < 17; i++) {
X if (lbl[i] == 0)
X break;
X }
X for (; i < 16; i++)
X lbl[i] = ' ';
X lbl[16] = 0;
X
X /* set up the parameters */
X cmd[2] = n; /* function key number */
X ptru.ptr = &lbl[0]; /* set up pointer to label string */
Xforce: cmd[4] = ptru.cstr[0];
X cmd[5] = ptru.cstr[1];
X cmd[6] = ptru.cstr[2];
X cmd[7] = ptru.cstr[3];
X
X /* and send it out */
X agios(&cmd[0], 12);
X return(TRUE);
X}
X#endif
X#else
X
Xh15hello()
X
X{
X}
X#endif
E!O!F
newsize=`wc -c < hp150.c`
if [ $newsize -ne 9192 ]
then echo "File hp150.c was $newsize bytes, 9192 expected"
fi
echo 'x - ibmpc.c (text)'
sed << 'E!O!F' 's/^X//' > ibmpc.c
X/*
X * The routines in this file provide support for the IBM-PC and other
X * compatible terminals. It goes directly to the graphics RAM to do
X * screen output. It compiles into nothing if not an IBM-PC driver
X * Supported monitor cards include CGA, MONO and EGA.
X */
X
X#define termdef 1 /* don't define "term" external */
X
X#include
X#include "estruct.h"
X#include "edef.h"
X
X#if IBMPC
X#define NROW 43 /* Max Screen size. */
X#define NCOL 80 /* Edit if you want to. */
X#define MARGIN 8 /* size of minimim margin and */
X#define SCRSIZ 64 /* scroll size for extended lines */
X#define NPAUSE 200 /* # times thru update to pause */
X#define BEL 0x07 /* BEL character. */
X#define ESC 0x1B /* ESC character. */
X#define SPACE 32 /* space character */
X
X#define SCADC 0xb8000000L /* CGA address of screen RAM */
X#define SCADM 0xb0000000L /* MONO address of screen RAM */
X#define SCADE 0xb8000000L /* EGA address of screen RAM */
X
X#define MONOCRSR 0x0B0D /* monochrome cursor */
X#define CGACRSR 0x0607 /* CGA cursor */
X#define EGACRSR 0x0709 /* EGA cursor */
X
X#define CDCGA 0 /* color graphics card */
X#define CDMONO 1 /* monochrome text card */
X#define CDEGA 2 /* EGA color adapter */
X#define CDSENSE 9 /* detect the card type */
X
X#define NDRIVE 3 /* number of screen drivers */
X
Xint dtype = -1; /* current display type */
Xchar drvname[][8] = { /* screen resolution names */
X "CGA", "MONO", "EGA"
X};
Xlong scadd; /* address of screen ram */
Xint *scptr[NROW]; /* pointer to screen lines */
Xint sline[NCOL]; /* screen line image */
Xint egaexist = FALSE; /* is an EGA card available? */
Xextern union REGS rg; /* cpu register for use of DOS calls */
X
Xextern int ttopen(); /* Forward references. */
Xextern int ttgetc();
Xextern int ttputc();
Xextern int ttflush();
Xextern int ttclose();
Xextern int ibmmove();
Xextern int ibmeeol();
Xextern int ibmeeop();
Xextern int ibmbeep();
Xextern int ibmopen();
Xextern int ibmrev();
Xextern int ibmcres();
Xextern int ibmclose();
Xextern int ibmputc();
Xextern int ibmkopen();
Xextern int ibmkclose();
X
X#if COLOR
Xextern int ibmfcol();
Xextern int ibmbcol();
X
Xint cfcolor = -1; /* current forground color */
Xint cbcolor = -1; /* current background color */
Xint ctrans[] = /* ansi to ibm color translation table */
X {0, 4, 2, 6, 1, 5, 3, 7};
X#endif
X
X/*
X * Standard terminal interface dispatch table. Most of the fields point into
X * "termio" code.
X */
XTERM term = {
X NROW-1,
X NROW-1,
X NCOL,
X NCOL,
X MARGIN,
X SCRSIZ,
X NPAUSE,
X ibmopen,
X ibmclose,
X ibmkopen,
X ibmkclose,
X ttgetc,
X ibmputc,
X ttflush,
X ibmmove,
X ibmeeol,
X ibmeeop,
X ibmbeep,
X ibmrev,
X ibmcres
X#if COLOR
X , ibmfcol,
X ibmbcol
X#endif
X};
X
Xextern union REGS rg;
X
X#if COLOR
Xibmfcol(color) /* set the current output color */
X
Xint color; /* color to set */
X
X{
X cfcolor = ctrans[color];
X}
X
Xibmbcol(color) /* set the current background color */
X
Xint color; /* color to set */
X
X{
X cbcolor = ctrans[color];
X}
X#endif
X
Xibmmove(row, col)
X{
X rg.h.ah = 2; /* set cursor position function code */
X rg.h.dl = col;
X rg.h.dh = row;
X rg.h.bh = 0; /* set screen page number */
X int86(0x10, &rg, &rg);
X}
X
Xibmeeol() /* erase to the end of the line */
X
X{
X int attr; /* attribute byte mask to place in RAM */
X int *lnptr; /* pointer to the destination line */
X int i;
X int ccol; /* current column cursor lives */
X int crow; /* row */
X
X /* find the current cursor position */
X rg.h.ah = 3; /* read cursor position function code */
X rg.h.bh = 0; /* current video page */
X int86(0x10, &rg, &rg);
X ccol = rg.h.dl; /* record current column */
X crow = rg.h.dh; /* and row */
X
X /* build the attribute byte and setup the screen pointer */
X#if COLOR
X if (dtype != CDMONO)
X attr = (((cbcolor & 15) << 4) | (cfcolor & 15)) << 8;
X else
X attr = 0x0700;
X#else
X attr = 0x0700;
X#endif
X lnptr = &sline[0];
X for (i=0; i < term.t_ncol; i++)
X *lnptr++ = SPACE | attr;
X
X if (flickcode && (dtype == CDCGA)) {
X /* wait for vertical retrace to be off */
X while ((inp(0x3da) & 8))
X ;
X
X /* and to be back on */
X while ((inp(0x3da) & 8) == 0)
X ;
X }
X
X /* and send the string out */
X movmem(&sline[0], scptr[crow]+ccol, (term.t_ncol-ccol)*2);
X
X}
X
Xibmputc(ch) /* put a character at the current position in the
X current colors */
X
Xint ch;
X
X{
X rg.h.ah = 14; /* write char to screen with current attrs */
X rg.h.al = ch;
X#if COLOR
X if (dtype != CDMONO)
X rg.h.bl = cfcolor;
X else
X rg.h.bl = 0x07;
X#else
X rg.h.bl = 0x07;
X#endif
X int86(0x10, &rg, &rg);
X}
X
Xibmeeop()
X{
X int attr; /* attribute to fill screen with */
X
X rg.h.ah = 6; /* scroll page up function code */
X rg.h.al = 0; /* # lines to scroll (clear it) */
X rg.x.cx = 0; /* upper left corner of scroll */
X rg.x.dx = (term.t_nrow << 8) | (term.t_ncol - 1);
X /* lower right corner of scroll */
X#if COLOR
X if (dtype != CDMONO)
X attr = ((ctrans[gbcolor] & 15) << 4) | (ctrans[gfcolor] & 15);
X else
X attr = 0;
X#else
X attr = 0;
X#endif
X rg.h.bh = attr;
X int86(0x10, &rg, &rg);
X}
X
Xibmrev(state) /* change reverse video state */
X
Xint state; /* TRUE = reverse, FALSE = normal */
X
X{
X /* This never gets used under the IBM-PC driver */
X}
X
Xibmcres(res) /* change screen resolution */
X
Xchar *res; /* resolution to change to */
X
X{
X int i; /* index */
X
X for (i = 0; i < NDRIVE; i++)
X if (strcmp(res, drvname[i]) == 0) {
X scinit(i);
X return(TRUE);
X }
X return(FALSE);
X}
X
Xspal() /* reset the pallette registers */
X
X{
X /* nothin here now..... */
X}
X
Xibmbeep()
X{
X#if MWC86
X putcnb(BEL);
X#else
X bdos(6, BEL, 0);
X#endif
X}
X
Xibmopen()
X{
X scinit(CDSENSE);
X revexist = TRUE;
X ttopen();
X}
X
Xibmclose()
X
X{
X#if COLOR
X ibmfcol(7);
X ibmbcol(0);
X#endif
X /* if we had the EGA open... close it */
X if (dtype == CDEGA)
X egaclose();
X
X ttclose();
X}
X
Xibmkopen() /* open the keyboard */
X
X{
X}
X
Xibmkclose() /* close the keyboard */
X
X{
X}
X
Xscinit(type) /* initialize the screen head pointers */
X
Xint type; /* type of adapter to init for */
X
X{
X union {
X long laddr; /* long form of address */
X int *paddr; /* pointer form of address */
X } addr;
X int i;
X
X /* if asked...find out what display is connected */
X if (type == CDSENSE)
X type = getboard();
X
X /* if we have nothing to do....don't do it */
X if (dtype == type)
X return(TRUE);
X
X /* if we try to switch to EGA and there is none, don't */
X if (type == CDEGA && egaexist != TRUE)
X return(FALSE);
X
X /* if we had the EGA open... close it */
X if (dtype == CDEGA)
X egaclose();
X
X /* and set up the various parameters as needed */
X switch (type) {
X case CDMONO: /* Monochrome adapter */
X scadd = SCADM;
X newsize(TRUE, 25);
X break;
X
X case CDCGA: /* Color graphics adapter */
X scadd = SCADC;
X newsize(TRUE, 25);
X break;
X
X case CDEGA: /* Enhanced graphics adapter */
X scadd = SCADE;
X egaopen();
X newsize(TRUE, 43);
X break;
X }
X
X /* reset the $sres environment variable */
X strcpy(sres, drvname[type]);
X dtype = type;
X
X /* initialize the screen pointer array */
X for (i = 0; i < NROW; i++) {
X addr.laddr = scadd + (long)(NCOL * i * 2);
X scptr[i] = addr.paddr;
X }
X}
X
X/* getboard: Determine which type of display board is attached.
X Current known types include:
X
X CDMONO Monochrome graphics adapter
X CDCGA Color Graphics Adapter
X CDEGA Extended graphics Adapter
X*/
X
X/* getbaord: Detect the current display adapter
X if MONO set to MONO
X CGA set to CGA EGAexist = FALSE
X EGA set to CGA EGAexist = TRUE
X*/
X
Xint getboard()
X
X{
X int type; /* board type to return */
X
X type = CDCGA;
X int86(0x11, &rg, &rg);
X if ((((rg.x.ax >> 4) & 3) == 3))
X type = CDMONO;
X
X /* test if EGA present */
X rg.x.ax = 0x1200;
X rg.x.bx = 0xff10;
X int86(0x10,&rg, &rg); /* If EGA, bh=0-1 and bl=0-3 */
X egaexist = !(rg.x.bx & 0xfefc); /* Yes, it's EGA */
X return(type);
X}
X
Xegaopen() /* init the computer to work with the EGA */
X
X{
X /* put the beast into EGA 43 row mode */
X rg.x.ax = 3;
X int86(16, &rg, &rg);
X
X rg.h.ah = 17; /* set char. generator function code */
X rg.h.al = 18; /* to 8 by 8 double dot ROM */
X rg.h.bl = 0; /* block 0 */
X int86(16, &rg, &rg);
X
X rg.h.ah = 18; /* alternate select function code */
X rg.h.al = 0; /* clear AL for no good reason */
X rg.h.bl = 32; /* alt. print screen routine */
X int86(16, &rg, &rg);
X
X rg.h.ah = 1; /* set cursor size function code */
X rg.x.cx = 0x0607; /* turn cursor on code */
X int86(0x10, &rg, &rg);
X
X outp(0x3d4, 10); /* video bios bug patch */
X outp(0x3d5, 6);
X}
X
Xegaclose()
X
X{
X /* put the beast into 80 column mode */
X rg.x.ax = 3;
X int86(16, &rg, &rg);
X}
X
Xscwrite(row, outstr, forg, bacg) /* write a line out*/
X
Xint row; /* row of screen to place outstr on */
Xchar *outstr; /* string to write out (must be term.t_ncol long) */
Xint forg; /* forground color of string to write */
Xint bacg; /* background color */
X
X{
X int attr; /* attribute byte mask to place in RAM */
X int *lnptr; /* pointer to the destination line */
X int i;
X
X /* build the attribute byte and setup the screen pointer */
X#if COLOR
X if (dtype != CDMONO)
X attr = (((ctrans[bacg] & 15) << 4) | (ctrans[forg] & 15)) << 8;
X else
X attr = (((bacg & 15) << 4) | (forg & 15)) << 8;
X#else
X attr = (((bacg & 15) << 4) | (forg & 15)) << 8;
X#endif
X lnptr = &sline[0];
X for (i=0; i input.c
X/* INPUT: Various input routines for MicroEMACS 3.7
X written by Daniel Lawrence
X 5/9/86 */
X
X#include
X#include "estruct.h"
X#include "edef.h"
X
X/*
X * Ask a yes or no question in the message line. Return either TRUE, FALSE, or
X * ABORT. The ABORT status is returned if the user bumps out of the question
X * with a ^G. Used any time a confirmation is required.
X */
X
Xmlyesno(prompt)
X
Xchar *prompt;
X
X{
X char c; /* input character */
X char buf[NPAT]; /* prompt to user */
X
X for (;;) {
X /* build and prompt the user */
X strcpy(buf, prompt);
X strcat(buf, " [y/n]? ");
X mlwrite(buf);
X
X /* get the responce */
X c = tgetc();
X
X if (c == ectoc(abortc)) /* Bail out! */
X return(ABORT);
X
X if (c=='y' || c=='Y')
X return(TRUE);
X
X if (c=='n' || c=='N')
X return(FALSE);
X }
X}
X
X/*
X * Write a prompt into the message line, then read back a response. Keep
X * track of the physical position of the cursor. If we are in a keyboard
X * macro throw the prompt away, and return the remembered response. This
X * lets macros run at full speed. The reply is always terminated by a carriage
X * return. Handle erase, kill, and abort keys.
X */
X
Xmlreply(prompt, buf, nbuf)
X char *prompt;
X char *buf;
X{
X return(nextarg(prompt, buf, nbuf, ctoec('\n')));
X}
X
Xmlreplyt(prompt, buf, nbuf, eolchar)
X
Xchar *prompt;
Xchar *buf;
Xint eolchar;
X
X{
X return(nextarg(prompt, buf, nbuf, eolchar));
X}
X
X/* ectoc: expanded character to character
X colapse the CTRL and SPEC flags back into an ascii code */
X
Xectoc(c)
X
Xint c;
X
X{
X if (c & CTRL)
X c = c & ~(CTRL | 0x40);
X if (c & SPEC)
X c= c & 255;
X return(c);
X}
X
X/* ctoec: character to extended character
X pull out the CTRL and SPEC prefixes (if possible) */
X
Xctoec(c)
X
Xint c;
X
X{
X if (c>=0x00 && c<=0x1F)
X c = CTRL | (c+'@');
X return (c);
X}
X
X/* get a command name from the command line. Command completion means
X that pressing a will attempt to complete an unfinished command
X name if it is unique.
X*/
X
Xint (*getname())()
X
X{
X#if ST520 & LATTICE
X#define register
X#endif
X register int cpos; /* current column on screen output */
X register int c;
X register char *sp; /* pointer to string for output */
X register NBIND *ffp; /* first ptr to entry in name binding table */
X register NBIND *cffp; /* current ptr to entry in name binding table */
X register NBIND *lffp; /* last ptr to entry in name binding table */
X char buf[NSTRING]; /* buffer to hold tentative command name */
X int (*fncmatch())();
X
X /* starting at the beginning of the string buffer */
X cpos = 0;
X
X /* if we are executing a command line get the next arg and match it */
X if (clexec) {
X if (macarg(buf) != TRUE)
X return(FALSE);
X return(fncmatch(&buf[0]));
X }
X
X /* build a name string from the keyboard */
X while (TRUE) {
X c = tgetc();
X
X /* if we are at the end, just match it */
X if (c == 0x0d) {
X buf[cpos] = 0;
X
X /* and match it off */
X return(fncmatch(&buf[0]));
X
X } else if (c == ectoc(abortc)) { /* Bell, abort */
X ctrlg(FALSE, 0);
X TTflush();
X return( (int (*)()) NULL);
X
X } else if (c == 0x7F || c == 0x08) { /* rubout/erase */
X if (cpos != 0) {
X TTputc('\b');
X TTputc(' ');
X TTputc('\b');
X --ttcol;
X --cpos;
X TTflush();
X }
X
X } else if (c == 0x15) { /* C-U, kill */
X while (cpos != 0) {
X TTputc('\b');
X TTputc(' ');
X TTputc('\b');
X --cpos;
X --ttcol;
X }
X
X TTflush();
X
X } else if (c == ' ') {
X/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
X /* attempt a completion */
X buf[cpos] = 0; /* terminate it for us */
X ffp = &names[0]; /* scan for matches */
X while (ffp->n_func != NULL) {
X if (strncmp(buf, ffp->n_name, strlen(buf)) == 0) {
X /* a possible match! More than one? */
X if ((ffp + 1)->n_func == NULL ||
X (strncmp(buf, (ffp+1)->n_name, strlen(buf)) != 0)) {
X /* no...we match, print it */
X sp = ffp->n_name + cpos;
X while (*sp)
X TTputc(*sp++);
X TTflush();
X return(ffp->n_func);
X } else {
X/* << << << << << << << << << << << << << << << << << */
X /* try for a partial match against the list */
X
X /* first scan down until we no longer match the current input */
X lffp = (ffp + 1);
X while ((lffp+1)->n_func != NULL) {
X if (strncmp(buf, (lffp+1)->n_name, strlen(buf)) != 0)
X break;
X ++lffp;
X }
X
X /* and now, attempt to partial complete the string, char at a time */
X while (TRUE) {
X /* add the next char in */
X buf[cpos] = ffp->n_name[cpos];
X
X /* scan through the candidates */
X cffp = ffp + 1;
X while (cffp <= lffp) {
X if (cffp->n_name[cpos] != buf[cpos])
X goto onward;
X ++cffp;
X }
X
X /* add the character */
X TTputc(buf[cpos++]);
X }
X/* << << << << << << << << << << << << << << << << << */
X }
X }
X ++ffp;
X }
X
X /* no match.....beep and onward */
X TTbeep();
Xonward:;
X TTflush();
X/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
X } else {
X if (cpos < NSTRING-1 && c > ' ') {
X buf[cpos++] = c;
X TTputc(c);
X }
X
X ++ttcol;
X TTflush();
X }
X }
X}
X
X/* tgetc: Get a key from the terminal driver, resolve any keyboard
X macro action */
X
Xint tgetc()
X
X{
X int c; /* fetched character */
X
X /* if we are playing a keyboard macro back, */
X if (kbdmode == PLAY) {
X
X /* if there is some left... */
X if (kbdptr < kbdend)
X return((int)*kbdptr++);
X
X /* at the end of last repitition? */
X if (--kbdrep < 1) {
X kbdmode = STOP;
X#if VISMAC == 0
X /* force a screen update after all is done */
X update(FALSE);
X#endif
X } else {
X
X /* reset the macro to the begining for the next rep */
X kbdptr = &kbdm[0];
X return((int)*kbdptr++);
X }
X }
X
X /* fetch a character from the terminal driver */
X c = TTgetc();
X
X /* record it for $lastkey */
X lastkey = c;
X
X /* save it if we need to */
X if (kbdmode == RECORD) {
X *kbdptr++ = c;
X kbdend = kbdptr;
X
X /* don't overrun the buffer */
X if (kbdptr == &kbdm[NKBDM - 1]) {
X kbdmode = STOP;
X TTbeep();
X }
X }
X
X /* and finally give the char back */
X return(c);
X}
X
X/* GET1KEY: Get one keystroke. The only prefixs legal here
X are the SPEC and CTRL prefixes.
X */
X
Xget1key()
X
X{
X int c;
X#if AMIGA
X int d;
X#endif
X
X /* get a keystroke */
X c = tgetc();
X
X#if MSDOS | ST520
X if (c == 0) { /* Apply SPEC prefix */
X c = tgetc();
X if (c>=0x00 && c<=0x1F) /* control key? */
X c = CTRL | (c+'@');
X return(SPEC | c);
X }
X#endif
X
X#if AMIGA
X /* apply SPEC prefix */
X if ((unsigned)c == 155) {
X c = tgetc();
X
X /* first try to see if it is a cursor key */
X if ((c >= 'A' && c <= 'D') || c == 'S' || c == 'T')
X return(SPEC | c);
X
X /* next, a 2 char sequence */
X d = tgetc();
X if (d == '~')
X return(SPEC | c);
X
X /* decode a 3 char sequence */
X c = d + 32;
X /* if a shifted function key, eat the tilde */
X if (d >= '0' && d <= '9')
X d = tgetc();
X return(SPEC | c);
X }
X#endif
X
X#if WANGPC
X if (c == 0x1F) { /* Apply SPEC prefix */
X c = tgetc();
X return(SPEC | c);
X }
X#endif
X
X if (c>=0x00 && c<=0x1F) /* C0 control -> C- */
X c = CTRL | (c+'@');
X return (c);
X}
X
X/* GETCMD: Get a command from the keyboard. Process all applicable
X prefix keys
X */
Xgetcmd()
X
X{
X int c; /* fetched keystroke */
X
X /* get initial character */
X c = get1key();
X
X /* process META prefix */
X if (c == metac) {
X c = get1key();
X if (islower(c)) /* Force to upper */
X c ^= DIFCASE;
X if (c>=0x00 && c<=0x1F) /* control key */
X c = CTRL | (c+'@');
X return(META | c);
X }
X
X /* process CTLX prefix */
X if (c == ctlxc) {
X c = get1key();
X if (c>='a' && c<='z') /* Force to upper */
X c -= 0x20;
X if (c>=0x00 && c<=0x1F) /* control key */
X c = CTRL | (c+'@');
X return(CTLX | c);
X }
X
X /* otherwise, just return it */
X return(c);
X}
X
X/* A more generalized prompt/reply function allowing the caller
X to specify the proper terminator. If the terminator is not
X a return ('\n') it will echo as ""
X */
Xgetstring(prompt, buf, nbuf, eolchar)
X
Xchar *prompt;
Xchar *buf;
Xint eolchar;
X
X{
X register int cpos; /* current character position in string */
X register int c;
X register int quotef; /* are we quoting the next char? */
X
X cpos = 0;
X quotef = FALSE;
X
X /* prompt the user for the input string */
X mlwrite(prompt);
X
X for (;;) {
X /* get a character from the user */
X c = get1key();
X
X /* If it is a , change it to a */
X if (c == (CTRL | 0x4d))
X c = CTRL | 0x40 | '\n';
X
X /* if they hit the line terminate, wrap it up */
X if (c == eolchar && quotef == FALSE) {
X buf[cpos++] = 0;
X
X /* clear the message line */
X mlwrite("");
X TTflush();
X
X /* if we default the buffer, return FALSE */
X if (buf[0] == 0)
X return(FALSE);
X
X return(TRUE);
X }
X
X /* change from command form back to character form */
X c = ectoc(c);
X
X if (c == ectoc(abortc) && quotef == FALSE) {
X /* Abort the input? */
X ctrlg(FALSE, 0);
X TTflush();
X return(ABORT);
X } else if ((c==0x7F || c==0x08) && quotef==FALSE) {
X /* rubout/erase */
X if (cpos != 0) {
X outstring("\b \b");
X --ttcol;
X
X if (buf[--cpos] < 0x20) {
X outstring("\b \b");
X --ttcol;
X }
X
X if (buf[cpos] == '\n') {
X outstring("\b\b \b\b");
X ttcol -= 2;
X }
X TTflush();
X }
X
X } else if (c == 0x15 && quotef == FALSE) {
X /* C-U, kill */
X while (cpos != 0) {
X outstring("\b \b");
X --ttcol;
X
X if (buf[--cpos] < 0x20) {
X outstring("\b \b");
X --ttcol;
X }
X }
X TTflush();
X
X } else if (c == quotec && quotef == FALSE) {
X quotef = TRUE;
X } else {
X quotef = FALSE;
X if (cpos < nbuf-1) {
X buf[cpos++] = c;
X
X if ((c < ' ') && (c != '\n')) {
X outstring("^");
X ++ttcol;
X c ^= 0x40;
X }
X
X if (c != '\n') {
X if (disinp)
X TTputc(c);
X } else { /* put out for */
X outstring("");
X ttcol += 3;
X }
X ++ttcol;
X TTflush();
X }
X }
X }
X}
X
Xoutstring(s) /* output a string of characters */
X
Xchar *s; /* string to output */
X
X{
X if (disinp)
X while (*s)
X TTputc(*s++);
X}
E!O!F
newsize=`wc -c < input.c`
if [ $newsize -ne 9954 ]
then echo "File input.c was $newsize bytes, 9954 expected"
fi
echo 'x - isearch.c (text)'
sed << 'E!O!F' 's/^X//' > isearch.c
X/*
X * The functions in this file implement commands that perform incremental
X * searches in the forward and backward directions. This "ISearch" command
X * is intended to emulate the same command from the original EMACS
X * implementation (ITS). Contains references to routines internal to
X * SEARCH.C.
X *
X * REVISION HISTORY:
X *
X * D. R. Banks 9-May-86
X * - added ITS EMACSlike ISearch
X *
X * John M. Gamble 5-Oct-86
X * - Made iterative search use search.c's scanner() routine.
X * This allowed the elimination of bakscan().
X * - Put isearch constants into estruct.h
X * - Eliminated the passing of 'status' to scanmore() and
X * checknext(), since there were no circumstances where
X * it ever equalled FALSE.
X */
X
X#include
X#include "estruct.h"
X#include "edef.h"
X
X#if ISRCH
X
Xextern int scanner(); /* Handy search routine */
Xextern int eq(); /* Compare chars, match case */
X
X/* A couple of "own" variables for re-eat */
X
Xint (*saved_get_char)(); /* Get character routine */
Xint eaten_char = -1; /* Re-eaten char */
X
X/* A couple more "own" variables for the command string */
X
Xint cmd_buff[CMDBUFLEN]; /* Save the command args here */
Xint cmd_offset; /* Current offset into command buff */
Xint cmd_reexecute = -1; /* > 0 if re-executing command */
X
X
X/*
X * Subroutine to do incremental reverse search. It actually uses the
X * same code as the normal incremental search, as both can go both ways.
X */
X
Xint risearch(f, n)
X{
X LINE *curline; /* Current line on entry */
X int curoff; /* Current offset on entry */
X
X /* remember the initial . on entry: */
X
X curline = curwp->w_dotp; /* Save the current line pointer */
X curoff = curwp->w_doto; /* Save the current offset */
X
X /* Make sure the search doesn't match where we already are: */
X
X backchar(TRUE, 1); /* Back up a character */
X
X if (!(isearch(f, -n))) /* Call ISearch backwards */
X { /* If error in search: */
X curwp->w_dotp = curline; /* Reset the line pointer */
X curwp->w_doto = curoff; /* and the offset to original value */
X curwp->w_flag |= WFMOVE; /* Say we've moved */
X update(FALSE); /* And force an update */
X mlwrite ("[search failed]"); /* Say we died */
X } else mlerase (); /* If happy, just erase the cmd line */
X}
X
X/* Again, but for the forward direction */
X
Xint fisearch(f, n)
X{
X LINE *curline; /* Current line on entry */
X int curoff; /* Current offset on entry */
X
X /* remember the initial . on entry: */
X
X curline = curwp->w_dotp; /* Save the current line pointer */
X curoff = curwp->w_doto; /* Save the current offset */
X
X /* do the search */
X
X if (!(isearch(f, n))) /* Call ISearch forwards */
X { /* If error in search: */
X curwp->w_dotp = curline; /* Reset the line pointer */
X curwp->w_doto = curoff; /* and the offset to original value */
X curwp->w_flag |= WFMOVE; /* Say we've moved */
X update(FALSE); /* And force an update */
X mlwrite ("[search failed]"); /* Say we died */
X } else mlerase (); /* If happy, just erase the cmd line */
X}
X
X/*
X * Subroutine to do an incremental search. In general, this works similarly
X * to the older micro-emacs search function, except that the search happens
X * as each character is typed, with the screen and cursor updated with each
X * new search character.
X *
X * While searching forward, each successive character will leave the cursor
X * at the end of the entire matched string. Typing a Control-S or Control-X
X * will cause the next occurrence of the string to be searched for (where the
X * next occurrence does NOT overlap the current occurrence). A Control-R will
X * change to a backwards search, META will terminate the search and Control-G
X * will abort the search. Rubout will back up to the previous match of the
X * string, or if the starting point is reached first, it will delete the
X * last character from the search string.
X *
X * While searching backward, each successive character will leave the cursor
X * at the beginning of the matched string. Typing a Control-R will search
X * backward for the next occurrence of the string. Control-S or Control-X
X * will revert the search to the forward direction. In general, the reverse
X * incremental search is just like the forward incremental search inverted.
X *
X * In all cases, if the search fails, the user will be feeped, and the search
X * will stall until the pattern string is edited back into something that
X * exists (or until the search is aborted).
X */
X
Xisearch(f, n)
X{
X int status; /* Search status */
X int col; /* prompt column */
X register int cpos; /* character number in search string */
X register int c; /* current input character */
X register int expc; /* function expanded input char */
X char pat_save[NPAT]; /* Saved copy of the old pattern str */
X LINE *curline; /* Current line on entry */
X int curoff; /* Current offset on entry */
X int init_direction; /* The initial search direction */
X
X /* Initialize starting conditions */
X
X cmd_reexecute = -1; /* We're not re-executing (yet?) */
X cmd_offset = 0; /* Start at the beginning of the buff */
X cmd_buff[0] = '\0'; /* Init the command buffer */
X strncpy (pat_save, pat, NPAT); /* Save the old pattern string */
X curline = curwp->w_dotp; /* Save the current line pointer */
X curoff = curwp->w_doto; /* Save the current offset */
X init_direction = n; /* Save the initial search direction */
X
X /* This is a good place to start a re-execution: */
X
Xstart_over:
X
X /* ask the user for the text of a pattern */
X col = promptpattern("ISearch: "); /* Prompt, remember the col */
X
X cpos = 0; /* Start afresh */
X status = TRUE; /* Assume everything's cool */
X
X /*
X Get the first character in the pattern. If we get an initial Control-S
X or Control-R, re-use the old search string and find the first occurrence
X */
X
X c = ectoc(expc = get_char()); /* Get the first character */
X if ((c == IS_FORWARD) ||
X (c == IS_REVERSE) ||
X (c == IS_VMSFORW)) /* Reuse old search string? */
X {
X for (cpos = 0; pat[cpos] != 0; cpos++) /* Yup, find the length */
X col = echochar(pat[cpos],col); /* and re-echo the string */
X if (c == IS_REVERSE) { /* forward search? */
X n = -1; /* No, search in reverse */
X backchar (TRUE, 1); /* Be defensive about EOB */
X } else
X n = 1; /* Yes, search forward */
X status = scanmore(pat, n); /* Do the search */
X c = ectoc(expc = get_char()); /* Get another character */
X }
X
X /* Top of the per character loop */
X
X for (;;) /* ISearch per character loop */
X {
X /* Check for special characters first: */
X /* Most cases here change the search */
X
X if (expc == metac) /* Want to quit searching? */
X return (TRUE); /* Quit searching now */
X
X switch (c) /* dispatch on the input char */
X {
X case IS_ABORT: /* If abort search request */
X return(FALSE); /* Quit searching again */
X
X case IS_REVERSE: /* If backward search */
X case IS_FORWARD: /* If forward search */
X case IS_VMSFORW: /* of either flavor */
X if (c == IS_REVERSE) /* If reverse search */
X n = -1; /* Set the reverse direction */
X else /* Otherwise, */
X n = 1; /* go forward */
X status = scanmore(pat, n); /* Start the search again */
X c = ectoc(expc = get_char()); /* Get the next char */
X continue; /* Go continue with the search*/
X
X case IS_NEWLINE: /* Carriage return */
X c = '\n'; /* Make it a new line */
X break; /* Make sure we use it */
X
X case IS_QUOTE: /* Quote character */
X case IS_VMSQUOTE: /* of either variety */
X c = ectoc(expc = get_char()); /* Get the next char */
X
X case IS_TAB: /* Generically allowed */
X case '\n': /* controlled characters */
X break; /* Make sure we use it */
X
X case IS_BACKSP: /* If a backspace: */
X case IS_RUBOUT: /* or if a Rubout: */
X if (cmd_offset <= 1) /* Anything to delete? */
X return (TRUE); /* No, just exit */
X --cmd_offset; /* Back up over the Rubout */
X cmd_buff[--cmd_offset] = '\0'; /* Yes, delete last char */
X curwp->w_dotp = curline; /* Reset the line pointer */
X curwp->w_doto = curoff; /* and the offset */
X n = init_direction; /* Reset the search direction */
X strncpy (pat, pat_save, NPAT); /* Restore the old search str */
X cmd_reexecute = 0; /* Start the whole mess over */
X goto start_over; /* Let it take care of itself */
X
X /* Presumably a quasi-normal character comes here */
X
X default: /* All other chars */
X if (c < ' ') /* Is it printable? */
X { /* Nope. */
X reeat (c); /* Re-eat the char */
X return (TRUE); /* And return the last status */
X }
X } /* Switch */
X
X /* I guess we got something to search for, so search for it */
X
X pat[cpos++] = c; /* put the char in the buffer */
X if (cpos >= NPAT) /* too many chars in string? */
X { /* Yup. Complain about it */
X mlwrite("? Search string too long");
X return(TRUE); /* Return an error */
X }
X pat[cpos] = 0; /* null terminate the buffer */
X col = echochar(c,col); /* Echo the character */
X if (!status) { /* If we lost last time */
X TTputc(BELL); /* Feep again */
X TTflush(); /* see that the feep feeps */
X } else /* Otherwise, we must have won*/
X if (!(status = checknext(c, pat, n))) /* See if match */
X status = scanmore(pat, n); /* or find the next match */
X c = ectoc(expc = get_char()); /* Get the next char */
X } /* for {;;} */
X}
X
X/*
X * Trivial routine to insure that the next character in the search string is
X * still true to whatever we're pointing to in the buffer. This routine will
X * not attempt to move the "point" if the match fails, although it will
X * implicitly move the "point" if we're forward searching, and find a match,
X * since that's the way forward isearch works.
X *
X * If the compare fails, we return FALSE and assume the caller will call
X * scanmore or something.
X */
X
Xint checknext (chr, patrn, dir) /* Check next character in search string */
Xchar chr; /* Next char to look for */
Xchar *patrn; /* The entire search string (incl chr) */
Xint dir; /* Search direction */
X{
X register LINE *curline; /* current line during scan */
X register int curoff; /* position within current line */
X register int buffchar; /* character at current position */
X int status; /* how well things go */
X
X
X /* setup the local scan pointer to current "." */
X
X curline = curwp->w_dotp; /* Get the current line structure */
X curoff = curwp->w_doto; /* Get the offset within that line */
X
X if (dir > 0) /* If searching forward */
X {
X if (curoff == llength(curline)) /* If at end of line */
X {
X curline = lforw(curline); /* Skip to the next line */
X if (curline == curbp->b_linep)
X return (FALSE); /* Abort if at end of buffer */
X curoff = 0; /* Start at the beginning of the line */
X buffchar = '\n'; /* And say the next char is NL */
X } else
X buffchar = lgetc(curline, curoff++); /* Get the next char */
X if (status = eq(buffchar, chr)) /* Is it what we're looking for? */
X {
X curwp->w_dotp = curline; /* Yes, set the buffer's point */
X curwp->w_doto = curoff; /* to the matched character */
X curwp->w_flag |= WFMOVE; /* Say that we've moved */
X }
X return (status); /* And return the status */
X } else /* Else, if reverse search: */
X return (match_pat (patrn)); /* See if we're in the right place */
X}
X
X/*
X * This hack will search for the next occurrence of in the buffer, either
X * forward or backward. It is called with the status of the prior search
X * attempt, so that it knows not to bother if it didn't work last time. If
X * we can't find any more matches, "point" is left where it was before. If
X * we do find a match, "point" will be at the end of the matched string for
X * forward searches and at the beginning of the matched string for reverse
X * searches.
X */
X
Xint scanmore(patrn, dir) /* search forward or back for a pattern */
Xchar *patrn; /* string to scan for */
Xint dir; /* direction to search */
X{
X int sts; /* search status */
X
X if (dir < 0) /* reverse search? */
X {
X rvstrcpy(tap, patrn); /* Put reversed string in tap */
X sts = scanner(tap, REVERSE, PTBEG);
X }
X else
X sts = scanner(patrn, FORWARD, PTEND); /* Nope. Go forward */
X
X if (!sts)
X {
X TTputc(BELL); /* Feep if search fails */
X TTflush(); /* see that the feep feeps */
X }
X
X return(sts); /* else, don't even try */
X}
X
X/*
X * The following is a worker subroutine used by the reverse search. It
X * compares the pattern string with the characters at "." for equality. If
X * any characters mismatch, it will return FALSE.
X *
X * This isn't used for forward searches, because forward searches leave "."
X * at the end of the search string (instead of in front), so all that needs to
X * be done is match the last char input.
X */
X
Xint match_pat (patrn) /* See if the pattern string matches string at "." */
Xchar *patrn; /* String to match to buffer */
X{
X register int i; /* Generic loop index/offset */
X register int buffchar; /* character at current position */
X register LINE *curline; /* current line during scan */
X register int curoff; /* position within current line */
X
X /* setup the local scan pointer to current "." */
X
X curline = curwp->w_dotp; /* Get the current line structure */
X curoff = curwp->w_doto; /* Get the offset within that line */
X
X /* top of per character compare loop: */
X
X for (i = 0; i < strlen(patrn); i++) /* Loop for all characters in patrn */
X {
X if (curoff == llength(curline)) /* If at end of line */
X {
X curline = lforw(curline); /* Skip to the next line */
X curoff = 0; /* Start at the beginning of the line */
X if (curline == curbp->b_linep)
X return (FALSE); /* Abort if at end of buffer */
X buffchar = '\n'; /* And say the next char is NL */
X } else
X buffchar = lgetc(curline, curoff++); /* Get the next char */
X if (!eq(buffchar, patrn[i])) /* Is it what we're looking for? */
X return (FALSE); /* Nope, just punt it then */
X }
X return (TRUE); /* Everything matched? Let's celebrate*/
X}
X
X/* Routine to prompt for I-Search string. */
X
Xint promptpattern(prompt)
Xchar *prompt;
X{
X char tpat[NPAT+20];
X
X strcpy(tpat, prompt); /* copy prompt to output string */
X strcat(tpat, " ["); /* build new prompt string */
X expandp(pat, &tpat[strlen(tpat)], NPAT/2); /* add old pattern */
X strcat(tpat, "]: ");
X
X /* check to see if we are executing a command line */
X if (!clexec) {
X mlwrite(tpat);
X }
X return(strlen(tpat));
X}
X
X/* routine to echo i-search characters */
X
Xint echochar(c,col)
Xint c; /* character to be echoed */
Xint col; /* column to be echoed in */
X{
X movecursor(term.t_nrow,col); /* Position the cursor */
X if ((c < ' ') || (c == 0x7F)) /* Control character? */
X {
X switch (c) /* Yes, dispatch special cases*/
X {
X case '\n': /* Newline */
X TTputc('<');
X TTputc('N');
X TTputc('L');
X TTputc('>');
X col += 3;
X break;
X
X case '\t': /* Tab */
X TTputc('<');
X TTputc('T');
X TTputc('A');
X TTputc('B');
X TTputc('>');
X col += 4;
X break;
X
X case 0x7F: /* Rubout: */
X TTputc('^'); /* Output a funny looking */
X TTputc('?'); /* indication of Rubout */
X col++; /* Count the extra char */
X break;
X
X default: /* Vanilla control char */
X TTputc('^'); /* Yes, output prefix */
X TTputc(c+0x40); /* Make it "^X" */
X col++; /* Count this char */
X }
X } else
X TTputc(c); /* Otherwise, output raw char */
X TTflush(); /* Flush the output */
X return(++col); /* return the new column no */
X}
X
X/*
X * Routine to get the next character from the input stream. If we're reading
X * from the real terminal, force a screen update before we get the char.
X * Otherwise, we must be re-executing the command string, so just return the
X * next character.
X */
X
Xint get_char ()
X{
X int c; /* A place to get a character */
X
X /* See if we're re-executing: */
X
X if (cmd_reexecute >= 0) /* Is there an offset? */
X if ((c = cmd_buff[cmd_reexecute++]) != 0)
X return (c); /* Yes, return any character */
X
X /* We're not re-executing (or aren't any more). Try for a real char */
X
X cmd_reexecute = -1; /* Say we're in real mode again */
X update(FALSE); /* Pretty up the screen */
X if (cmd_offset >= CMDBUFLEN-1) /* If we're getting too big ... */
X {
X mlwrite ("? command too long"); /* Complain loudly and bitterly */
X return (metac); /* And force a quit */
X }
X c = get1key(); /* Get the next character */
X cmd_buff[cmd_offset++] = c; /* Save the char for next time */
X cmd_buff[cmd_offset] = '\0';/* And terminate the buffer */
X return (c); /* Return the character */
X}
X
X/*
X * Hacky routine to re-eat a character. This will save the character to be
X * re-eaten by redirecting the input call to a routine here. Hack, etc.
X */
X
X/* Come here on the next term.t_getchar call: */
X
Xint uneat()
X{
X int c;
X
X term.t_getchar = saved_get_char; /* restore the routine address */
X c = eaten_char; /* Get the re-eaten char */
X eaten_char = -1; /* Clear the old char */
X return(c); /* and return the last char */
X}
X
Xint reeat(c)
Xint c;
X{
X if (eaten_char != -1) /* If we've already been here */
X return/*(NULL)*/; /* Don't do it again */
X eaten_char = c; /* Else, save the char for later */
X saved_get_char = term.t_getchar; /* Save the char get routine */
X term.t_getchar = uneat; /* Replace it with ours */
X}
X#else
Xisearch()
X{
X}
X#endif
E!O!F
newsize=`wc -c < isearch.c`
if [ $newsize -ne 18697 ]
then echo "File isearch.c was $newsize bytes, 18697 expected"
fi
bill davidsen (wedu@ge-crd.arpa)
{chinet | philabs | sesimo}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me