home *** CD-ROM | disk | FTP | other *** search
- /* $Id: term.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
- *
- * $Log: term.c,v $
- * Revision 4.4.3.1 1992/02/01 03:09:32 sob
- * Release 4.4 Patchlevel 3
- *
- * Revision 4.4.2.1 1991/12/01 18:05:42 sob
- * Patchlevel 2 changes
- *
- * Revision 4.4 1991/09/09 20:27:37 sob
- * release 4.4
- *
- *
- *
- */
- /* This software is Copyright 1991 by Stan Barber.
- *
- * Permission is hereby granted to copy, reproduce, redistribute or otherwise
- * use this software as long as: there is no monetary profit gained
- * specifically from the use or reproduction of this software, it is not
- * sold, rented, traded or otherwise marketed, and this copyright notice is
- * included prominently in any copy made.
- *
- * The author make no claims as to the fitness or correctness of this software
- * for any use whatsoever, and it is provided as is. Any use of this software
- * is at the user's own risk.
- */
-
- #include "EXTERN.h"
- #include "common.h"
- #include "util.h"
- #include "final.h"
- #include "help.h"
- #include "cheat.h"
- #include "intrp.h"
- #include "INTERN.h"
- #include "term.h"
-
-
- char ERASECH; /* rubout character */
- char KILLCH; /* line delete character */
- char tcarea[TCSIZE]; /* area for "compiled" termcap strings */
-
- #ifdef USETHREADS
- int upcost;
- #endif
-
- /* guarantee capability pointer != Nullch */
- /* (I believe terminfo will ignore the &tmpaddr argument.) */
-
- #define Tgetstr(key) ((tmpstr = tgetstr(key,&tmpaddr)) ? tmpstr : nullstr)
-
- #ifdef PUSHBACK
- struct keymap {
- char km_type[128];
- union km_union {
- struct keymap *km_km;
- char *km_str;
- } km_ptr[128];
- };
-
- #define KM_NOTHIN 0
- #define KM_STRING 1
- #define KM_KEYMAP 2
- #define KM_BOGUS 3
-
- #define KM_TMASK 3
- #define KM_GSHIFT 4
- #define KM_GMASK 7
-
- typedef struct keymap KEYMAP;
-
- KEYMAP *topmap INIT(Null(KEYMAP*));
-
- void mac_init();
- KEYMAP *newkeymap();
- void show_keymap();
- void pushstring();
- #endif
-
- void line_col_calcs();
-
- /* terminal initialization */
-
- void
- term_init()
- {
- savetty(); /* remember current tty state */
-
- #ifdef TERMIO
- outspeed = _tty.c_cflag & CBAUD; /* for tputs() */
- ERASECH = _tty.c_cc[VERASE]; /* for finish_command() */
- KILLCH = _tty.c_cc[VKILL]; /* for finish_command() */
- if (GT = ((_tty.c_oflag & TABDLY) != TAB3))
- /* we have tabs, so that's OK */;
- else
- _tty.c_oflag &= ~TAB3; /* turn off kernel tabbing -- done in rn */
- #else /* !TERMIO */
- # ifdef TERMIOS
- outspeed = cfgetospeed(&_tty); /* for tputs() (output) */
- ERASECH = _tty.c_cc[VERASE]; /* for finish_command() */
- KILLCH = _tty.c_cc[VKILL]; /* for finish_command() */
- /* _tty.c_oflag &= ~OXTABS; /* turn off kernel tabbing-done in rn */
- # else /* !TERMIOS */
- outspeed = _tty.sg_ospeed; /* for tputs() */
- ERASECH = _tty.sg_erase; /* for finish_command() */
- KILLCH = _tty.sg_kill; /* for finish_command() */
- if (GT = ((_tty.sg_flags & XTABS) != XTABS))
- /* we have tabs, so that's OK */;
- else
- _tty.sg_flags &= ~XTABS;
- # endif /* TERMIOS */
- #endif /* TERMIO */
-
- /* The following could be a table but I can't be sure that there isn't */
- /* some degree of sparsity out there in the world. */
-
- switch (outspeed) { /* 1 second of padding */
- #ifdef BEXTA
- case BEXTA: just_a_sec = 1920; break;
- #else
- #ifdef B19200
- case B19200: just_a_sec = 1920; break;
- #endif
- #endif
- case B9600: just_a_sec = 960; break;
- case B4800: just_a_sec = 480; break;
- case B2400: just_a_sec = 240; break;
- case B1800: just_a_sec = 180; break;
- case B1200: just_a_sec = 120; break;
- case B600: just_a_sec = 60; break;
- case B300: just_a_sec = 30; break;
- /* do I really have to type the rest of this??? */
- case B200: just_a_sec = 20; break;
- case B150: just_a_sec = 15; break;
- case B134: just_a_sec = 13; break;
- case B110: just_a_sec = 11; break;
- case B75: just_a_sec = 8; break;
- case B50: just_a_sec = 5; break;
- default: just_a_sec = 960; break;
- /* if we are running detached I */
- } /* don't want to know about it! */
- }
-
- /* set terminal characteristics */
-
- void
- term_set(tcbuf)
- char *tcbuf; /* temp area for "uncompiled" termcap entry */
- {
- char *tmpaddr; /* must not be register */
- register char *tmpstr;
- char *tgetstr();
- char *s;
- int status;
- #ifdef TIOCGWINSZ
- struct winsize winsize;
- #endif
-
- #ifdef PENDING
- #if ! defined (FIONREAD) && ! defined (RDCHK)
- /* do no delay reads on something that always gets closed on exit */
-
- devtty = open("/dev/tty",0);
- if (devtty < 0) {
- printf(cantopen,"/dev/tty") ; FLUSH;
- finalize(1);
- }
- fcntl(devtty,F_SETFL,O_NDELAY);
- #endif
- #endif
-
- /* get all that good termcap stuff */
-
- #ifdef HAVETERMLIB
- status = tgetent(tcbuf,getenv("TERM")); /* get termcap entry */
- if (status < 1) {
- #ifdef VERBOSE
- printf("No termcap %s found.\n", status ? "file" : "entry") ; FLUSH;
- #else
- fputs("Termcap botch\n",stdout) ; FLUSH;
- #endif
- finalize(1);
- }
- tmpaddr = tcarea; /* set up strange tgetstr pointer */
- s = Tgetstr("pc"); /* get pad character */
- PC = *s; /* get it where tputs wants it */
- if (!tgetflag("bs")) { /* is backspace not used? */
- BC = Tgetstr("bc"); /* find out what is */
- if (BC == nullstr) /* terminfo grok's 'bs' but not 'bc' */
- BC = Tgetstr("le");
- } else
- BC = "\b"; /* make a backspace handy */
- UP = Tgetstr("up"); /* move up a line */
- if (!*UP) /* no UP string? */
- marking = 0; /* disable any marking */
- if (muck_up_clear) /* this is for weird HPs */
- CL = "\n\n\n\n";
- else
- CL = Tgetstr("cl"); /* get clear string */
- CE = Tgetstr("ce"); /* clear to end of line string */
- TI = Tgetstr("ti"); /* initialize display */
- TE = Tgetstr("te"); /* reset display */
- #if defined(CLEAREOL) || defined(USETHREADS)
- HO = Tgetstr("ho"); /* home cursor if no CM */
- CM = Tgetstr("cm"); /* cursor motion */
- if (*CM || *HO)
- can_home = TRUE;
- #endif
- #ifdef CLEAREOL
- CD = Tgetstr("cd"); /* clear to end of display */
- if (!*CE || !*CD || !can_home) /* can we CE, CD, and home? */
- can_home_clear = FALSE; /* no, so disable use of clear eol */
- if (!*CE) CE = CD;
- #endif /* CLEAREOL */
- #ifdef USETHREADS
- upcost = strlen(UP);
- #endif
- SO = Tgetstr("so"); /* begin standout */
- SE = Tgetstr("se"); /* end standout */
- if ((SG = tgetnum("sg"))<0)
- SG = 0; /* blanks left by SG, SE */
- US = Tgetstr("us"); /* start underline */
- UE = Tgetstr("ue"); /* end underline */
- if ((UG = tgetnum("ug"))<0)
- UG = 0; /* blanks left by US, UE */
- if (*US)
- UC = nullstr; /* UC must not be NULL */
- else
- UC = Tgetstr("uc"); /* underline a character */
- if (!*US && !*UC) { /* no underline mode? */
- US = SO; /* substitute standout mode */
- UE = SE;
- UG = SG;
- }
- LINES = tgetnum("li"); /* lines per page */
- /*** OS2: The number of columns must reduced by one, so that ***
- *** the internal pagers break the line, before the ***
- *** line is broken by the 'terminal' ***/
- COLS = tgetnum("co"); /* columns on page */
- if (COLS > 2) --COLS;
- #ifdef TIOCGWINSZ
- { struct winsize ws;
- if (ioctl(0, TIOCGWINSZ, &ws) >= 0 && ws.ws_row > 0 && ws.ws_col > 0) {
- LINES = ws.ws_row;
- COLS = ws.ws_col - 1;
- }
- }
- #endif
-
- AM = tgetflag("am"); /* terminal wraps automatically? */
- XN = tgetflag("xn"); /* then eats next newline? */
- VB = Tgetstr("vb");
- if (!*VB)
- VB = "\007";
- CR = Tgetstr("cr");
- if (!*CR) {
- if (tgetflag("nc") && *UP) {
- CR = safemalloc((MEM_SIZE)strlen(UP)+2);
- sprintf(CR,"%s\r",UP);
- }
- else
- CR = "\r";
- }
- #ifdef TIOCGWINSZ
- if (ioctl(1, TIOCGWINSZ, &winsize)>=0) {
- if (winsize.ws_row>0) LINES=winsize.ws_row;
- if (winsize.ws_col>0) COLS=winsize.ws_col - 1;
- }
- #endif
- #else
- ?????? /* Roll your own... */
- #endif
- termlib_init();
- line_col_calcs();
- noecho(); /* turn off echo */
- crmode(); /* enter cbreak mode */
-
- #ifdef PUSHBACK
- mac_init(tcbuf);
- #endif
- }
-
- #ifdef PUSHBACK
- void
- mac_init(tcbuf)
- char *tcbuf;
- {
- char tmpbuf[1024];
-
- tmpfp = fos2open(filexp(getval("RNMACRO",RNMACRO)),"r");
- if (tmpfp != Nullfp) {
- while (fgets(tcbuf,1024,tmpfp) != Nullch) {
- mac_line(tcbuf,tmpbuf,(sizeof tmpbuf));
- }
- fclose(tmpfp);
- }
- }
-
- void
- mac_line(line,tmpbuf,tbsize)
- char *line;
- char *tmpbuf;
- int tbsize;
- {
- register char *s, *m;
- register KEYMAP *curmap;
- register int ch;
- register int garbage = 0;
- static char override[] = "\nkeymap overrides string\n";
-
- if (topmap == Null(KEYMAP*))
- topmap = newkeymap();
- if (*line == '#' || *line == '\n')
- return;
- if (line[ch = strlen(line)-1] == '\n')
- line[ch] = '\0';
- m = dointerp(tmpbuf,tbsize,line," \t");
- if (!*m)
- return;
- while (*m == ' ' || *m == '\t') m++;
- for (s=tmpbuf,curmap=topmap; *s; s++) {
- ch = *s & 0177;
- if (s[1] == '+' && isdigit(s[2])) {
- s += 2;
- garbage = (*s & KM_GMASK) << KM_GSHIFT;
- }
- else
- garbage = 0;
- if (s[1]) {
- if ((curmap->km_type[ch] & KM_TMASK) == KM_STRING) {
- fputs(override,stdout) ; FLUSH;
- free(curmap->km_ptr[ch].km_str);
- curmap->km_ptr[ch].km_str = Nullch;
- }
- curmap->km_type[ch] = KM_KEYMAP + garbage;
- if (curmap->km_ptr[ch].km_km == Null(KEYMAP*))
- curmap->km_ptr[ch].km_km = newkeymap();
- curmap = curmap->km_ptr[ch].km_km;
- }
- else {
- if ((curmap->km_type[ch] & KM_TMASK) == KM_KEYMAP) {
- fputs(override,stdout) ; FLUSH;
- }
- else {
- curmap->km_type[ch] = KM_STRING + garbage;
- curmap->km_ptr[ch].km_str = savestr(m);
- }
- }
- }
- }
-
- KEYMAP*
- newkeymap()
- {
- register int i;
- register KEYMAP *map;
-
- #ifndef lint
- map = (KEYMAP*)safemalloc(sizeof(KEYMAP));
- #else
- map = Null(KEYMAP*);
- #endif /* lint */
- for (i=127; i>=0; --i) {
- map->km_ptr[i].km_km = Null(KEYMAP*);
- map->km_type[i] = KM_NOTHIN;
- }
- return map;
- }
-
- void
- show_macros()
- {
- char prebuf[64];
-
- if (topmap != Null(KEYMAP*)) {
- print_lines("Macros:\n",STANDOUT);
- *prebuf = '\0';
- show_keymap(topmap,prebuf);
- }
- else {
- print_lines("No macros defined.\n", NOMARKING);
- }
- }
-
- void
- show_keymap(curmap,prefix)
- register KEYMAP *curmap;
- char *prefix;
- {
- register int i;
- register char *next = prefix + strlen(prefix);
- register int kt;
-
- for (i=0; i<128; i++) {
- if (kt = curmap->km_type[i]) {
- if (i < ' ')
- sprintf(next,"^%c",i+64);
- else if (i == ' ')
- strcpy(next,"\\040");
- else if (i == 127)
- strcpy(next,"^?");
- else
- sprintf(next,"%c",i);
- if ((kt >> KM_GSHIFT) & KM_GMASK) {
- sprintf(cmd_buf,"+%d", (kt >> KM_GSHIFT) & KM_GMASK);
- strcat(next,cmd_buf);
- }
- switch (kt & KM_TMASK) {
- case KM_NOTHIN:
- sprintf(cmd_buf,"%s %c\n",prefix,i);
- print_lines(cmd_buf,NOMARKING);
- break;
- case KM_KEYMAP:
- show_keymap(curmap->km_ptr[(char)i].km_km, prefix);
- break;
- case KM_STRING:
- sprintf(cmd_buf,"%s %s\n",prefix,curmap->km_ptr[i].km_str);
- print_lines(cmd_buf,NOMARKING);
- break;
- case KM_BOGUS:
- sprintf(cmd_buf,"%s BOGUS\n",prefix);
- print_lines(cmd_buf,STANDOUT);
- break;
- }
- }
- }
- }
-
- #endif
-
- /* routine to pass to tputs */
-
- char
- putchr(ch)
- register char_int ch;
- {
- putchar(ch);
- #ifdef lint
- ch = Null(char);
- ch = ch;
- #endif
- return((char) 0);
- }
-
- /* input the 2nd and succeeding characters of a multi-character command */
- /* returns TRUE if command finished, FALSE if they rubbed out first character */
-
- bool
- finish_command(donewline)
- int donewline;
- {
- register char *s;
- register bool quoteone = FALSE;
-
- s = buf;
- if (s[1] != FINISHCMD) /* someone faking up a command? */
- return TRUE;
- do {
- top:
- if (*(unsigned char *)s < ' ') {
- putchar('^');
- putchar(*s | 64);
- }
- else if (*s == '\177') {
- putchar('^');
- putchar('?');
- }
- else
- putchar(*s); /* echo previous character */
- s++;
- re_read:
- fflush(stdout);
- getcmd(s);
- if (quoteone) {
- quoteone = FALSE;
- continue;
- }
- if (errno || *s == '\f') {
- *s = Ctl('r'); /* force rewrite on CONT */
- }
- if (*s == '\033') { /* substitution desired? */
- #ifdef ESCSUBS
- char tmpbuf[4], *cpybuf;
-
- tmpbuf[0] = '%';
- read_tty(&tmpbuf[1],1);
- #ifdef RAWONLY
- tmpbuf[1] &= 0177;
- #endif
- tmpbuf[2] = '\0';
- if (tmpbuf[1] == 'h') {
- (void) help_subs();
- *s = '\0';
- reprint();
- goto re_read;
- }
- else if (tmpbuf[1] == '\033') {
- *s = '\0';
- cpybuf = savestr(buf);
- interp(buf, (sizeof buf), cpybuf);
- free(cpybuf);
- s = buf + strlen(buf);
- reprint();
- goto re_read;
- }
- else {
- interp(s,(sizeof buf) - (s-buf),tmpbuf);
- fputs(s,stdout);
- s += strlen(s);
- }
- goto re_read;
- #else
- notincl("^[");
- *s = '\0';
- reprint();
- goto re_read;
- #endif
- }
- else if (*s == ERASECH) { /* they want to rubout a char? */
- rubout();
- s--; /* discount the char rubbed out */
- if (*(unsigned char *)s < ' ' || *s == '\177')
- rubout();
- if (s == buf) { /* entire string gone? */
- fflush(stdout); /* return to single char command mode */
- return FALSE;
- }
- else
- goto re_read;
- }
- else if (*s == KILLCH) { /* wipe out the whole line? */
- while (s-- != buf) { /* emulate that many ERASEs */
- rubout();
- if (*(unsigned char *)s < ' ' || *s == '\177')
- rubout();
- }
- fflush(stdout);
- return FALSE; /* return to single char mode */
- }
- #ifdef WORDERASE
- else if (*s == Ctl('w')) { /* wipe out one word? */
- *s-- = ' ';
- while (!isspace(*s) || isspace(s[1])) {
- rubout();
- if (s-- == buf) {
- fflush(stdout);
- return FALSE; /* return to single char mode */
- }
- if (*(unsigned char *)s < ' ' || *s == '\177')
- rubout();
- }
- s++;
- goto re_read;
- }
- #endif
- else if (*s == Ctl('r')) {
- *s = '\0';
- reprint();
- goto re_read;
- }
- else if (*s == Ctl('v')) {
- putchar('^');
- backspace();
- fflush(stdout);
- getcmd(s);
- goto top;
- }
- else if (*s == '\\') {
- quoteone = TRUE;
- }
- /*** OS2: end on newline-character or cr-character ***/
- } while ((*s != '\r') && (*s != '\n'));
- /*#ifdef cray */
- /* } while (*s != '\r'); /* till a newline (not echoed) */
- /*#else
- /* } while (*s != '\n'); /* till a newline (not echoed) */
- /*#endif */
- *s = '\0'; /* terminate the string nicely */
- if (donewline)
- putchar('\n') ; FLUSH;
- return TRUE; /* say we succeeded */
- }
-
- /* discard any characters typed ahead */
-
- void
- eat_typeahead()
- {
- #ifdef PUSHBACK
- if (!typeahead && nextin==nextout) /* cancel only keyboard stuff */
- #else
- if (!typeahead)
- #endif
- {
- #ifdef PENDING
- while (input_pending())
- read_tty(buf,sizeof(buf));
- #else /* this is probably v7 */
- #if defined(TERMIO) || defined(TERMIOS)
- ioctl(_tty_ch,TCSETAW,&_tty);
- #else
- ioctl(_tty_ch,TIOCSETP,&_tty);
- #endif
- #endif
- }
- }
-
- void
- settle_down()
- {
- dingaling();
- fflush(stdout);
- /* sleep(1); */
- #ifdef PUSHBACK
- nextout = nextin; /* empty circlebuf */
- #endif
- eat_typeahead();
- }
-
- #ifdef PUSHBACK
- /* read a character from the terminal, with multi-character pushback */
-
- int
- read_tty(addr,size)
- char *addr;
- int size;
- {
-
- /*** OS2: we need this tmp-variables */
- int tmp_char, tmp_size;
-
- if (nextout != nextin) {
- *addr = circlebuf[nextout++];
- nextout %= PUSHSIZE;
- return 1;
- }
- else {
-
- /*** OS2: hmm..., I want to read only one character without
- pressing cr. How can this be realized ???
- We display the read character in this routine, but
- the cursor will remain on the same position. This is
- done by calling backspace(). This is necessary,
- because some of the functions which call read_tty,
- display the character themselved, but some don't do
- that, for example if it is a one character command. **/
-
- /* size = read(0,addr,size); */
-
- tmp_size = 0;
- while ((tmp_size < size) &&
- (tmp_char != 13) &&
- (tmp_char != 10)) {
- tmp_char = _read_kbd(0,1,0);
- /* I don't know why, but there is a coredump
- if we try to use the echo flag ...???
- But that's not a problem, because we don't
- want an echo. */
- addr[tmp_size] = (unsigned char)tmp_char;
- tmp_size++;
- }
- size = tmp_size;
-
- #ifdef RAWONLY
- *addr &= 0177;
- #endif
- return size;
- }
- }
-
- #ifdef PENDING
- #if ! defined (FIONREAD) && ! defined (RDCHK)
- int
- circfill()
- {
- register int Howmany;
-
- errno = 0;
- Howmany = read(devtty,circlebuf+nextin,1);
-
- if (Howmany < 0 && (errno == EAGAIN || errno == EINTR))
- Howmany = 0;
- if (Howmany) {
- nextin += Howmany;
- nextin %= PUSHSIZE;
- }
- return Howmany;
- }
- #endif /* PENDING */
- #endif /* FIONREAD */
-
- void
- pushchar(c)
- char_int c;
- {
- nextout--;
- if (nextout < 0)
- nextout = PUSHSIZE - 1;
- if (nextout == nextin) {
- fputs("\npushback buffer overflow\n",stdout) ; FLUSH;
- sig_catcher(0);
- }
- circlebuf[nextout] = c;
- }
-
- #else /* PUSHBACK */
- #ifndef read_tty
- /* read a character from the terminal, with hacks for O_NDELAY reads */
-
- int
- read_tty(addr,size)
- char *addr;
- int size;
- {
- if (is_input) {
- *addr = pending_ch;
- is_input = FALSE;
- return 1;
- }
- else {
- size = read(0,addr,size);
- #ifdef RAWONLY
- *addr &= 0177;
- #endif
- return size;
- }
- }
- #endif /* read_tty */
- #endif /* PUSHBACK */
-
- /* print an underlined string, one way or another */
-
- void
- underprint(s)
- register char *s;
- {
- assert(UC);
- if (*UC) { /* char by char underline? */
- while (*s) {
- if (*(unsigned char *)s < ' ') {
- putchar('^');
- backspace();/* back up over it */
- underchar();/* and do the underline */
- putchar(*s+64);
- backspace();/* back up over it */
- underchar();/* and do the underline */
- }
- else {
- putchar(*s);
- backspace();/* back up over it */
- underchar();/* and do the underline */
- }
- s++;
- }
- }
- else { /* start and stop underline */
- underline(); /* start underlining */
- while (*s) {
- if (*(unsigned char *)s < ' ') {
- putchar('^');
- putchar(*s+64);
- }
- else
- putchar(*s);
- s++;
- }
- un_underline(); /* stop underlining */
- }
- }
-
- /* keep screen from flashing strangely on magic cookie terminals */
-
- #ifdef NOFIREWORKS
- void
- no_sofire()
- {
- if (*UP && *SE) { /* should we disable fireworks? */
- putchar('\n');
- un_standout();
- up_line();
- carriage_return();
- }
- }
-
- void
- no_ulfire()
- {
- if (*UP && *US) { /* should we disable fireworks? */
- putchar('\n');
- un_underline();
- up_line();
- carriage_return();
- }
- }
- #endif
-
- /* get a character into a buffer */
-
- void
- getcmd(whatbuf)
- register char *whatbuf;
- {
- #ifdef PUSHBACK
- register KEYMAP *curmap;
- register int i;
- bool no_macros;
- int times = 0; /* loop detector */
- char scrchar;
-
- tryagain:
- curmap = topmap;
- no_macros = (whatbuf != buf && nextin == nextout);
- #endif
- for (;;) {
- int_count = 0;
- errno = 0;
- if (read_tty(whatbuf,1) < 0){
- if (!errno)
- errno = EINTR;
- if (errno == EINTR)
- return;
- perror(readerr);
- sig_catcher(0);
- }
- #ifdef PUSHBACK
- if (*whatbuf & 0200 || no_macros) {
- *whatbuf &= 0177;
- goto got_canonical;
- }
- if (curmap == Null(KEYMAP*))
- goto got_canonical;
- for (i = (curmap->km_type[*whatbuf] >> KM_GSHIFT) & KM_GMASK; i; --i){
- read_tty(&scrchar,1);
- }
- switch (curmap->km_type[*whatbuf] & KM_TMASK) {
- case KM_NOTHIN: /* no entry? */
- if (curmap == topmap) /* unmapped canonical */
- goto got_canonical;
- settle_down();
- goto tryagain;
- case KM_KEYMAP: /* another keymap? */
- curmap = curmap->km_ptr[*whatbuf].km_km;
- assert(curmap != Null(KEYMAP*));
- break;
- case KM_STRING: /* a string? */
- pushstring(curmap->km_ptr[*whatbuf].km_str);
- if (++times > 20) { /* loop? */
- fputs("\nmacro loop?\n",stdout);
- settle_down();
- }
- no_macros = FALSE;
- goto tryagain;
- }
- #else
- #ifdef RAWONLY
- *whatbuf &= 0177;
- #endif
- break;
- #endif
- }
-
- got_canonical:
- #if !defined(TERMIO) && !defined(TERMIOS)
- if (*whatbuf == '\r')
- *whatbuf = '\n';
- #endif
- if (whatbuf == buf)
- whatbuf[1] = FINISHCMD; /* tell finish_command to work */
- }
-
- #ifdef PUSHBACK
- void
- pushstring(str)
- char *str;
- {
- register int i;
- char tmpbuf[PUSHSIZE];
- register char *s = tmpbuf;
-
- assert(str != Nullch);
- interp(s,PUSHSIZE,str);
- for (i = strlen(s)-1; i >= 0; --i) {
- s[i] ^= 0200;
- pushchar(s[i]);
- }
- }
- #endif
-
- int
- get_anything()
- {
- char tmpbuf[2];
-
- reask_anything:
- unflush_output(); /* disable any ^O in effect */
- standout();
- #ifdef VERBOSE
- IF(verbose)
- fputs("[Type space to continue] ",stdout);
- ELSE
- #endif
- #ifdef TERSE
- fputs("[MORE] ",stdout);
- #endif
- un_standout();
- fflush(stdout);
- eat_typeahead();
- if (int_count) {
- return -1;
- }
- collect_subjects(); /* loads subject cache until */
- /* input is pending */
- getcmd(tmpbuf);
- if (errno || *tmpbuf == '\f') {
- putchar('\n') ; FLUSH; /* if return from stop signal */
- goto reask_anything; /* give them a prompt again */
- }
- if (*tmpbuf == 'h') {
- #ifdef VERBOSE
- IF(verbose) {
- fputs("\nType q to quit or space to continue.\n",stdout) ; FLUSH;
- }
- ELSE
- #endif
- #ifdef TERSE
- fputs("\nq to quit, space to continue.\n",stdout) ; FLUSH;
- #endif
- goto reask_anything;
- }
- else if (*tmpbuf != ' ' && *tmpbuf != '\n') {
- carriage_return();
- erase_eol(); /* erase the prompt */
- carriage_return();
- return *tmpbuf == 'q' ? -1 : *tmpbuf;
- }
- if (*tmpbuf == '\n') {
- page_line = LINES - 1;
- carriage_return();
- erase_eol();
- carriage_return();
- }
- else {
- page_line = 1;
- if (erase_screen) /* -e? */
- clear(); /* clear screen */
- else {
- carriage_return();
- erase_eol(); /* erase the prompt */
- carriage_return();
- }
- }
- return 0;
- }
-
- #ifdef USETHREADS
- int
- pause_getcmd()
- {
- unflush_output(); /* disable any ^O in effect */
- standout();
- #ifdef VERBOSE
- IF(verbose)
- fputs("[Type space or a command] ",stdout);
- ELSE
- #endif
- #ifdef TERSE
- fputs("[CMD] ",stdout);
- #endif
- un_standout();
- fflush(stdout);
- eat_typeahead();
- if (int_count) {
- return -1;
- }
- getcmd(buf);
- if (errno || *buf == '\f') {
- return 0; /* if return from stop signal */
- }
- else if (*buf != ' ') {
- carriage_return();
- erase_eol(); /* erase the prompt */
- carriage_return();
- return *buf;
- }
- return 0;
- }
- #endif
-
- void
- in_char(prompt, newmode)
- char *prompt;
- char_int newmode;
- {
- char oldmode = mode;
-
- reask_in_char:
- unflush_output(); /* disable any ^O in effect */
- fputs(prompt,stdout);
- fflush(stdout);
- eat_typeahead();
- mode = newmode;
- getcmd(buf);
- if (errno || *buf == '\f') {
- putchar('\n') ; FLUSH; /* if return from stop signal */
- goto reask_in_char; /* give them a prompt again */
- }
- mode = oldmode;
- }
-
- int
- print_lines(what_to_print,hilite)
- char *what_to_print;
- int hilite;
- {
- register char *s;
- register int i;
-
- /*** OS2: this is only a temporary patch, blank out
- \r-characters when printing ***/
- for (s=what_to_print;*s!='\0';++s)
- if (*s == '\r') *s = ' ';
- /*** end of patch ***/
- if (page_line < 0) /* they do not want to see this? */
- return -1;
- for (s=what_to_print; *s; ) {
- if (page_line >= LINES || int_count) {
- if (i = -1, int_count || (i = get_anything())) {
- page_line = -1; /* disable further print_lines */
- return i;
- }
- }
- page_line++;
- if (hilite == STANDOUT) {
- #ifdef NOFIREWORKS
- if (erase_screen)
- no_sofire();
- #endif
- standout();
- }
- else if (hilite == UNDERLINE) {
- #ifdef NOFIREWORKS
- if (erase_screen)
- no_ulfire();
- #endif
- underline();
- }
- for (i=0; i<COLS; i++) {
- if (!*s)
- break;
- if (*(unsigned char *)s >= ' ')
- putchar(*s);
- else if (*s == '\t') {
- putchar(*s);
- i = ((i+8) & ~7) - 1;
- }
- else if (*s == '\n') {
- i = 32000;
- }
- else {
- i++;
- putchar('^');
- putchar(*s + 64);
- }
- s++;
- }
- if (i) {
- if (hilite == STANDOUT)
- un_standout();
- else if (hilite == UNDERLINE)
- un_underline();
- if (AM && i == COLS)
- fflush(stdout);
- else
- putchar('\n') ; FLUSH;
- }
- }
- return 0;
- }
-
- void
- page_init()
- {
- page_line = 1;
- if (erase_screen)
- clear();
- else
- putchar('\n') ; FLUSH;
- }
-
- void
- pad(num)
- int num;
- {
- register int i;
-
- for (i = num; i; --i)
- putchar(PC);
- fflush(stdout);
- }
-
- /* echo the command just typed */
-
- #ifdef VERIFY
- void
- printcmd()
- {
- if (verify && buf[1] == FINISHCMD) {
- if (*(unsigned char *)buf < ' ') {
- putchar('^');
- putchar(*buf | 64);
- backspace();
- backspace();
- }
- else {
- putchar(*buf);
- backspace();
- }
- fflush(stdout);
- }
- }
- #endif
-
- void
- rubout()
- {
- backspace(); /* do the old backspace, */
- putchar(' '); /* space, */
- backspace(); /* backspace trick */
- }
-
- void
- reprint()
- {
- register char *s;
-
- fputs("^R\n",stdout) ; FLUSH;
- for (s = buf; *s; s++) {
- if (*(unsigned char *)s < ' ') {
- putchar('^');
- putchar(*s | 64);
- }
- else
- putchar(*s);
- }
- }
-
- #if defined(CLEAREOL) || defined(USETHREADS)
- void
- home_cursor()
- {
- char *tgoto();
-
- if (!*HO) { /* no home sequence? */
- if (!*CM) { /* no cursor motion either? */
- fputs ("\n\n\n", stdout);
- return; /* forget it. */
- }
- tputs (tgoto (CM, 0, 0), 1, putchr); /* go to home via CM */
- return;
- }
- else { /* we have home sequence */
- tputs (HO, 1, putchr); /* home via HO */
- }
- }
- #endif
-
- #ifdef USETHREADS
- void
- goto_line(from,to) /* assumes caller is already at beginning of line */
- int from,to;
- {
- char *tgoto(), *str;
- int cmcost;
-
- if (from == to) {
- return;
- }
- if (*CM && !muck_up_clear) {
- cmcost = strlen(str = tgoto(CM,0,to));
- } else {
- cmcost = 9999;
- }
- if (to > from) {
- go_down:
- if (to - from <= cmcost) {
- while(from++ < to) {
- putchar('\n');
- }
- return;
- }
- } else if(*UP) {
- if ((from - to) * upcost <= cmcost) {
- while(from-- > to) {
- tputs(UP,1,putchr);
- }
- return;
- }
- } else if (cmcost == 9999) {
- home_cursor();
- from = 0;
- goto go_down;
- }
- tputs(str,1,putchr);
- }
- #endif
-
- void
- line_col_calcs()
- {
- if (LINES > 0) { /* is this a crt? */
- if ((!initlines) || (!initlines_specified))
- /* no -i or unreasonable value for initlines */
- if (outspeed >= B9600) /* whole page at >= 9600 baud */
- initlines = LINES;
- else if (outspeed >= B4800)/* 16 lines at 4800 */
- initlines = 16;
- else /* otherwise just header */
- initlines = 8;
- }
- else { /* not a crt */
- LINES = 30000; /* so don't page */
- CL = "\n\n"; /* put a couple of lines between */
- if ((!initlines) || (!initlines_specified))
- /* make initlines reasonable */
- initlines = 8;
- }
- if (COLS <= 0)
- COLS = 79;
- }
-
-
- #ifdef SIGWINCH
- SIGRET
- winch_catcher(dummy)
- int dummy;
- {
- /* Reset signal in case of System V dain bramage */
- sigset(SIGWINCH, winch_catcher);
-
- /* Come here if window size change signal received */
- #ifdef TIOCGWINSZ
- { struct winsize ws;
- if (ioctl(0, TIOCGWINSZ, &ws) >= 0 && ws.ws_row > 0 && ws.ws_col > 0) {
- LINES = ws.ws_row;
- COLS = ws.ws_col - 1;
- line_col_calcs();
- }
- }
- #else
- /* Well, if SIGWINCH is defined, but TIOCGWINSZ isn't, there's */
- /* almost certainly something wrong. Figure it out for yourself, */
- /* because I don't know now to deal :-) */
- #endif
- }
- #endif
- void
- termlib_init()
- {
- #ifdef USETITE
- if (TI && *TI)
- tputs (TI,1,putchr);
- #endif
- return;
- }
- void
- termlib_reset()
- {
- #ifdef USETITE
- if (TE && *TE)
- tputs (TE,1,putchr);
- #endif
- return;
- }
-