|
|
researchv9-SUN3(old)
#include <stdio.h>
#ifdef ux3
#include <termio.h>
#else
#include <sgtty.h>
#endif
/* EMACS_MODES: c !fill */
char *getenv();
/* macro definitions */
#define EOL '\n'
char *UP; /* cursor up line */
char *DOWN;
char *BACK;
char *FORWARD;
char *HOME;
char *CLEAR;
char *CLREST;
char *CLINE;
char *BELL;
char *CURAD;
char *TMAP;
char *SMAP;
char *NOP;
char *LOPEN;
char *LDEL;
char *INSERTC;
char *INSERTM;
char *OSERTC;
char *INSERTP;
char *DELC;
char *SSCROLL;
char *RSCROLL;
char *CR;
char *SCREG;
char *ULINE;
char *UEND;
int EOVER;
char *SCINIT;
char *VEXIT;
char *RELDOWN;
char *RELUP;
char *RELFORW;
char *RELBACK;
int XBASE;
int YBASE;
int SCRWID;
int SCRNLIN;
int SCRWRAP;
int VCOST;
int SRCADD;
int MI;
int IN;
int DELMODE;
/* character definitions */
#define META 0200
#define MTA(mtach) ('mtach'+0200) /* make meta char */
#define ESC 033
#define NEWLINE 037
#define RUB 0177
/* DISPLAY MODE PARAMETERS */
int WRAPON = 0; /* perform ! processing at EOL */
int INSON = 0; /* use INSERTC/DELC */
/* screen display data */
char ttobuf[BUFSIZ];
int drain;
int mline;
int mcol;
int SCRLINES; /* number of lines in window */
int ECHOL; /* line for prompting */
int MODLN; /* line for buffer and file data */
/* statistics */
long nmput; /* calls to mputc */
long noutc; /* actual characters output */
int ninch; /* number of characters input */
int ntwrite; /* number of terminal writes */
int nbwrite; /* number of buffer writes */
int nbseek; /* number of seeks of buffer */
int nbread; /* number of buffer reads */
int nmkline; /* number of makeline calls */
extern int errno;
/* function definitions */
char *getname();
/*VARARGS*/ char *execl();
/* lint definitions */
#ifdef lint
#define IGNORE(x) if(x);
#else
#define IGNORE(x) (x)
#endif
/* emacs display definitions */
/* EMACS_MODES: c !fill */
char ldchar; /* last clobbered character */
char ldcol; /* collumn of ldchar */
char osert = 0; /* flag indicating insert char mode */
int acost; /* cost of absolute positioning */
int lUP; /* cost of UP */
int lDOWN; /* cost of DOWN */
int lBAK; /* cost of BACK */
int lCR;
int psx;
int psy;
int saveline;
int savecol;
int scrlin;
int scrcol;
int ttywarp; /* tty warp factor (stty speed) */
/* display data */
#define TTYLEN 256 /* total area for tty data strings */
char ttystrings[TTYLEN];
struct sparm {
char *t_pname;
int *t_padd;
};
struct sparm ttydata[] = {
"up",(int *) &UP,
"do",(int *) &DOWN,
"bc",(int *) &BACK,
"nd",(int *) &FORWARD,
"ho",(int *) &HOME,
"cl",(int *) &CLEAR,
"cd",(int *) &CLREST,
"ce",(int *) &CLINE,
"bl",(int *) &BELL,
"cm",(int *) &CURAD,
"tm",(int *) &TMAP,
"tM",(int *) &SMAP,
"pc",(int *) &NOP,
"al",(int *) &LOPEN,
"dl",(int *) &LDEL,
"ic",(int *) &INSERTC,
"im",(int *) &INSERTM,
"ei",(int *) &OSERTC,
"ip",(int *) &INSERTP,
"dc",(int *) &DELC,
"sf",(int *) &SSCROLL,
"sr",(int *) &RSCROLL,
"cr",(int *) &CR,
"cs",(int *) &SCREG,
"ul",(int *) &ULINE,
"ue",(int *) &UEND,
"eo",&EOVER,
"vs",(int *) &SCINIT,
"ve",(int *) &VEXIT,
"bx",&XBASE,
"by",&YBASE,
"co",&SCRWID,
"li",&SCRNLIN,
"am",&SCRWRAP,
"vc",(int *) &VCOST,
"rc",(int *) &SRCADD,
"mi",(int *) &MI,
"in",(int *) &IN,
"dm",&DELMODE,
"ru",(int *) &RELUP,
"rd",(int *) &RELDOWN,
"rl",(int *) &RELFORW,
"rr",(int *) &RELBACK,
0,0,
};
char *endput = "____________________";
#define SCRCONT '!'
int TABSTOP = 8;
#define NSCRLIN 48 /* max screen lines */
#define NSCRCOL 128 /* max screen columns */
char cmap[NSCRLIN] [NSCRCOL];
int scrjnk[NSCRLIN]; /* column of last non-white character */
/* character type table */
#define PLAIN 0
#define CONTRL 1
#define TAB 2
#define BACKSP 3
char ctype[128] = {
CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL,
BACKSP, TAB, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL,
CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL,
CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL,
PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, CONTRL,
};
/* display heuristics */
#define CFILL 30 /* average chars/line */
#define PATIENCE 2000 /* number of millisecends of */
/* output to buffer before */
/* looking for type ahead */
/* display macros */
#define mputc(chr) (((mcol<scrjnk[mline]) && (chr == cmap[mline][mcol]))? mcol++ : mptc(chr))
/* trace stuff */
char *termdir = SDIR/terminals/%s";
/* Terminal I/O modes, sgttyb for before unix 3.0, termio for later */
int SREGION = 24;
#ifdef ux3
struct termio ttyjunk;
#else
struct sgttyb ttyjunk;
#endif
int ttyerase = '#';
int ttykill = '@';
int ttyintr = '';
int ttyeof = '';
#define NBAUD 16 /* number of baud rates */
char charms[NBAUD] = { /* ms per char in various rates */
100,
100, /* 50 */
100, /* 75 */
100, /* 110 */
70, /* 134 */
66, /* 150 */
50, /* 200 */
33, /* 300 */
16, /* 600 */
8, /* 1200 */
5, /* 1800 */
4, /* 2400 */
2, /* 4800 */
1, /* 9600 */
1, /* EXTA */
1, /* EXTB */
};
xgo(x,y)
{
ldchar = 0;
mline = x;
mcol = y;
}
/* beep -- obvious */
beep()
{
PUTS(BELL); /* print a bell */
}
/* move both the display matrix pointer and the actual display to the
* specified line and column */
mgo(x,y)
register x,y;
{
sgo(mline = x,mcol = y);
}
/* move the display cursor to the specified destination. sgo attempts
* to optimize the movement, using single character or absolute
* positioning */
sgo(x,y)
register x,y;
{
int mx,my;
int xcost; /* cost with all relative movement */
int ycost; /* cost with carriage return */
/* acost is cost of absolute positioning */
/* calculate relative costs of various movements. cost functions */
/* automatically indicate that un-doable motions have infinite cost */
/* calculate xcost and ycost */
mx = x-scrlin;
if (mx<0) {
mx = -mx;
xcost = mx*lUP;
} else xcost = mx*lDOWN;
ycost = y + xcost + lCR;
my = y-scrcol;
if (my<0) {
my = -my;
xcost +=my*lBAK;
} else xcost += my;
if (acost < ycost) {
if (acost < xcost) {
/* do absolute positioning */
if (CURAD) { /* have absolute addrs */
if (SRCADD) {
eprintf(CURAD,x+XBASE,y+YBASE);
} else {
eprintf(CURAD,y+YBASE,x+XBASE);
}
} else { /* have relative addrs */
if (x>scrlin) printf (RELDOWN,mx);
if (x<scrlin) printf (RELUP,mx);
if (y>scrcol) printf (RELFORW,my);
if (y<scrcol) printf (RELBACK,my);
}
scrlin=x;
scrcol=y;
return;
} /* else relative is cheap, do it */
} else {
if (osert && (MI == 0)) {
unsert();
}
if (ycost < xcost) { /* do carriage return processing */
PUTS(CR); /* carriage return */
scrcol = 0;
/* fall through to finish with relative motion */
}
}
while (x != scrlin) {
if (x < scrlin) {
PUTS(UP);
scrlin--;
} else {
PUTS(DOWN);
scrlin++;
}
}
/* now correct row */
while (y != scrcol) {
if (y < scrcol) {
PUTS(BACK);
scrcol--;
} else {
if (FORWARD == NULL) {
if (osert) {
unsert();
}
x = cmap[scrlin] [scrcol];
if ((x == 0)|| (scrjnk[scrlin]<=scrcol)) x=cmap[scrlin] [scrcol] = ' ';
putit(x); /* re-write */
} else {
PUTS(FORWARD);
}
scrcol++;
}
};
return;
}
/* unsert -- LEAVE insert character mode */
unsert()
{
eprintf(OSERTC); /* can't stay inserting */
osert = 0;
}
/* a simple guide to all of the various putc routines in this program:
* xputc puts a character out, translating control and meta characters
* to prefix sequences, and calling sputc to put out the individual
* characters. sputc checks for end of line, and if so wraps to the
* next line. sputc calls mputc to output characters. mputc updates
* the next character in the display to be whaat is put out. Display
* takes place only if the character on the screen is not that called for
* already. */
mptc(c)
register c;
{
nmput++; /* count for stats */
if ((c == ' ') && (mcol >= scrjnk[mline])) {
cmap[mline] [mcol++] = c;
return;
}
if ((mcol != scrcol) || (mline != scrlin)) sgo(mline,mcol);
if (DELC && INSON && (c == cmap [mline] [mcol+1]) && (mcol+3 <scrjnk[mline]) && (ldchar == 0)) {
register i;
SREGION=scrjnk[mline]-mcol; /* number of char's gobbled */
if (DELMODE && (osert == 0)) {
eprintf(INSERTM);
osert++;
}
eprintf(DELC); /*clobber next char */
for (i = mcol; i <=scrjnk[mline];i++) {
cmap[mline] [i] = cmap[mline] [i+1];
}
scrjnk[mline]--;
} else {
if ((INSERTC || INSERTM) && INSON && (c == ldchar) && (mcol == ldcol+1) && (mcol<scrjnk[mline])) {
register i;
if (INSERTM && (osert == 0)) {
eprintf(INSERTM); /* open space */
osert = 1;
}
if (scrjnk[mline] >SCRWID) scrjnk[mline]--;
for (i = scrjnk[mline]++; i >= mcol;i--) {
cmap[mline] [i+1] = cmap[mline] [i];
}
if (INSERTC) eprintf(INSERTC);
cmap[mline] [mcol] = 0;
} else {
if (osert) {
unsert();
}
}
putit(c);
if (osert && INSERTP) eprintf(INSERTP);
if (ldchar == 0) ldcol = mcol; /* remember where it was */
ldchar = cmap[mline][mcol]; /* save last clobber */
if ((scrcol++ >= SCRWID) && SCRWRAP) {
scrlin++;
scrcol=0;
}
}
cmap[mline] [mcol] = c;
while (scrjnk[mline] <mcol) cmap[mline] [scrjnk[mline]++] = ' ';
if (++mcol> scrjnk[mline]) scrjnk[mline] = mcol;
}
/* getname prompts for a string, using ps, and inputs a string */
/* rubout and @ can be used to edit the string as enterred, and causes
* a quit, returning no input string
* ^Y causes the current buffer name to be brought out
*/
#define FNLEN 128
char fnbuf[FNLEN];
char *
getname(ps)
register char *ps;
{
register i;
register char c;
char *xp;
fnbuf[i=0] = 0;
for (;;) {
prompt1("%s%s",ps,fnbuf); /* display prompt */
mgo(mline,mcol);
c = mgetchar();
if ((c == '') || (c == ttyintr)) {
beep();
unprompt();
return(NULL);
}
if ((c == '
') || (c == '\n')) {
unprompt();
return(fnbuf);
}
if (c == ttyerase) {
if (i) {
i--;
fnbuf[i] = 0;
} else beep();
continue;
}
if (c == ttykill) {
fnbuf[i=0]=0;
continue;
}
if (c == '') {
c = 0177 & getchar();
}
fnbuf[i++] = c;
if (i >= FNLEN) {
beep();
--i;
}
fnbuf[i] = 0;
continue;
}
}
/* putout outputs a string (like eprintf) at the current position */
/* position is advanced one line. If the position overflows the screen,
* -MORE- is printed, and input is read. Any character except ^G
* continues the display, ^G quits by returning -1 */
/*VARARGS1*/
putout(string,arg1,arg2,arg3,arg4,arg5,arg6)
char *string;
{
if (mline>=SCRLINES) {
prompt1("-- MORE --");
if ((mgetchar()) == ttykill) return(-1);
unprompt();
mline=0; /* TOP */
}
prompt(mline,string,arg1,arg2,arg3,arg4,arg5,arg6);
clrl();
mgo(++mline,0);
return(0);
}
/* put out a string on ECHOL */
/*VARARGS1*/
prompt1(string,arg1,arg2,arg3,arg4,arg5)
char *string;
{
prompt(ECHOL,string,arg1,arg2,arg3,arg4,arg5);
}
/* put out a string at a specified line */
/*VARARGS2*/
prompt(ecl,string,arg1,arg2,arg3,arg4,arg5,arg6)
char *string;
register int ecl;
{
char pbuf[256];
if (mline<=SCRLINES) {
saveline = mline;
savecol = mcol;
}
mline = ecl;
mcol = 0;
seprintf(pbuf,string,arg1,arg2,arg3,arg4,arg5,arg6);
sputs(pbuf);
psx = mline;
psy = mcol;
clrl();
}
/* clear out prompt */
unprompt()
{
if (mline<=SCRLINES) { /* if position to save */
saveline = mline;
savecol = mcol;
}
mgo(ECHOL,0);
clrl();
mgo(saveline,savecol);
}
/* return to the position saved before the last prompt */
goback()
{
mgo(saveline,savecol);
}
/* put one character on the screen checking for end of screen line */
sputc(c)
register c;
{
register i;
if (mcol == SCRWID) {
if (WRAPON) {
if (mline>=NSCRLIN-1) {
mline--; /* don't run overboard */
} else {
mputc(SCRCONT);
mline++;
}
ldchar = 0; /* reset ldchar */
mcol = 0;
} else {
mputc(c);
mline++;
mcol=0;
ldchar=0;
return;
}
}
mputc(c);
}
/* put one character in the display, checking for control and meta chars. */
xputc(c)
register c;
{
register i;
c &= 0377;
if (c & META) {
sputc('M');
sputc('-');
c-= META;
}
switch(ctype[c]) {
char oc;
case PLAIN:
if ((!ULINE)||(!EOVER)) {
sputc(c);
return;
}
if (scrjnk[mline] <= mcol) {
sputc(c);
return;
}
oc = cmap[mline][mcol] & 0177 ;
if ((oc == '_') && ((c & 0177) != ' ')
&& ((c & 0177) != '_')) {
sputc(0200 | c);
return;
}
sputc(c);
return;
case BACKSP:
if ((ULINE)&&(EOVER)) {
if (mcol != 0) xgo(mline,mcol-1);
return;
}
/* NO BREAK HERE */
case CONTRL:
sputc('^');
sputc(c^0100);
return;
case TAB:
i = TABSTOP-(mcol%TABSTOP);
while (i--) sputc(' ');
return;
}
}
/* clear the rest of the line, checking to see if the line previously
* displayed corresponds to the one displayed here now */
clrl()
{
register x;
register y;
register z;
int xline;
int xcol;
ldchar = 0; /* wipe out last char */
x = mline;
z = mcol;
y = scrjnk[mline] - mcol;
if (y > 0) {
sgo(mline,mcol); /* go for real */
if (CLINE) {
SREGION=y; /* Number of characters cleared */
eprintf(CLINE);
} else {
xline = mline;
xcol = mcol;
while (y--) mputc (' ');
mgo(xline,xcol);
}
scrjnk[x] = z;
}
}
/* put a string on the screen, translating control and meta */
sputs(xp)
register char *xp;
{
register c;
while (c= *xp++) {
if (c == NEWLINE) {
if (mline < NSCRLIN) mline++; /* don't overflow */
mcol = 0;
xputc(' ');
} else xputc(c);
}
}
clear()
{
register int i;
eprintf(CLEAR);
for (i = 0; i < NSCRLIN; i++) scrjnk[i] = 0;
scrlin = scrcol = mline = mcol = 0;
}
/* Refresh the screen. Clears and then restores what we think is there */
rfrsh()
{
register xline;
register xcol;
eprintf(CLEAR);
scrlin=scrcol=0;
for (xline = 0; xline < SCRNLIN; xline++) {
for (xcol = 0; xcol < scrjnk[xline]; xcol++) {
if (cmap[xline][xcol]) {
sgo(xline,xcol);
putit(cmap[xline][xcol]);
if ((scrcol++ >= SCRWID) && SCRWRAP) {
scrlin++;
scrcol=0;
}
}
}
}
ldchar = 0;
}
sdelay(ms)
register int ms; /* milliseconds of delay */
{
register i;
for (i = 0; i < ms;) {
PUTS(NOP); /* idle */
i+=ttywarp; /* milliseconds/character */
}
}
ttype() /* set terminal type */
{
register char *mp;
mp = getname("Terminal Type? ");
if (mp == NULL) return;
sttype(mp);
}
int ttyptr = 0;
/* terminal description file parser: */
/* terminal description file contains lines with
parameter=data
* where data is either a number of a string */
ttyparse(mp)
char *mp;
{
register FILE *file;
char xbuf[128];
char optbuf[128];
register char *cp;
register int c;
struct sparm *parmp;
int parm;
/* find the terminal file and open it */
seprintf(xbuf,termdir,mp); /* terminal file */
file = fopen(xbuf,"r");
if (file == NULL) file = fopen(mp,"r");
if (file == NULL) {
eprintf ("Can't use terminal type %s\n", mp);
return(0);
}
/* first find what option we are setting */
nextparm: cp = optbuf;
while ((c = getc(file)) != '=') {
if (c == '\n') goto nextparm; /* comment line */
if (c == EOF) {
fclose(file);
return(1); /* abort during option scan */
}
*cp++=c;
}
*cp = 0;
/* look up parameter in parameter table */
for (parmp = ttydata; parmp->t_pname; parmp++) {
if ((optbuf[0]==parmp->t_pname[0])&& (optbuf[1]==parmp->t_pname[1])) {
c = getc(file);
if ((c >= '0') && (c <= '9')) {
parm = 0;
while ((c >= '0') && (c <= '9')) {
parm = 10*parm + (c-'0');
c = getc(file);
}
*(parmp->t_padd) = parm;
if (c != EOF) goto nextparm;
fclose(file);
return(1);
}
*(parmp->t_padd) = ((int) &ttystrings[ttyptr]);
while ((c != EOF) && (c != EOL)) {
if (c == '\\') {
c = getc(file);
if (c == 'n') c = '\n';
}
ttystrings[ttyptr++] = c;
c = getc(file);
}
ttystrings[ttyptr++] = 0;
if (c != EOF) goto nextparm;
}
}
goto nextparm;
}
PUTS(string)
char *string;
{
if (!drain) while(*string) putchar(0177 & *string++);
}
sttype(mp)
register char *mp;
{
register struct sparm *parmp;
/* First, initialize the tty data */
ttyptr = 0;
for (parmp = ttydata; parmp->t_pname; parmp++) {
*(parmp->t_padd) = 0;
}
SCRLINES=20;
SCRWID=80; /* so we won't bomb */
if (ttyparse(mp)) {
SCRWID--;
if (SCRNLIN>NSCRLIN) {
SCRNLIN=NSCRLIN;
}
if (SCRWID>NSCRCOL-1) {
SCRWID=NSCRCOL-1;
}
if (VCOST == 0) VCOST = 1;
SCRLINES = SCRNLIN-4;
ECHOL = SCRNLIN-1;
MODLN = SCRNLIN-3;
if (CURAD) {
acost = dcost(CURAD);
} else {
acost = dcost(RELUP)+dcost(RELFORW);
}
lUP = dcost(UP);
lDOWN = dcost(DOWN);
lBAK = dcost(BACK);
lCR = dcost(CR);
if (OSERTC && (INSERTM == 0)) {
INSERTM=INSERTC; /* old style insert modes */
INSERTC=0;
}
if (SCREG) LOPEN = SCREG; /* make sure we use SCREG */
if ((NOP == NULL) || (*NOP == 0)) NOP = "\200"; /* null pads get lost */
if (SCINIT) {
eprintf(SCINIT); /* initialize screen */
}
clear();
}
}
/* dcost -- calculate display cost of a string */
dcost(sp)
register char *sp;
{
register int dc;
if (sp == NULL) return(1000); /* infinite cost for missing capability */
dc = 0;
while (*sp) {
if (*sp++ != '%') dc++;
}
return(dc);
}
/* yes or no question */
/*VARARGS1*/
int
gyn(string,arg1,arg2,arg3)
char *string;
char *arg1;
char *arg2;
char *arg3;
{
register char c;
while (1) {
prompt(ECHOL,string,arg1,arg2,arg3);
sgo(mline,mcol);
c = mgetchar();
switch(c) {
case 'y':
case 'Y':
case ' ':
return(1);
case '': /* This is necessary to insure exit */
case 'n':
case 'N':
case '':
return(0);
case '':
return(-1);
default:
prompt(ECHOL-1,"y for yes, n for no, ^G to quit");
}
}
};
/* mtop -- move to top of display for message output */
mtop()
{
mgo(0,0); /* for messages */
}
uncook()
{
/* UNIX 3 code thanks to J. Langer and M. Plotnick */
#ifdef ux3
struct termio nttyjunk;
ioctl(1, TCGETA, &ttyjunk);
nttyjunk=ttyjunk;
#ifdef u370
nttyjunk.c_iflag |= (BRKINT|ISTRIP|IGNPAR);
nttyjunk.c_iflag &=
~(IGNBRK|IGNPAR|PARMRK|IXON|INLCR|IGNCR|ICRNL|INPCK);
/* accept break, no crnl mapping, no ^S^Q */
nttyjunk.c_oflag = 0; /* no delays, no crlf mapping */
nttyjunk.c_cflag |= CS8 ;
nttyjunk.c_lflag &= ~(ISIG|ECHO|ICANON); /* no echo, signals,
or erase/kill processing */
#else
nttyjunk.c_iflag |= (BRKINT|ISTRIP);
nttyjunk.c_iflag &= ~(IGNBRK|PARMRK|INLCR|ICRNL|IGNCR|IXON|IXOFF);
/* accept break, no crnl mapping, no ^S^Q */
nttyjunk.c_oflag = 0; /* no delays, no crlf mapping */
nttyjunk.c_lflag &= ~(ISIG|ECHO|ICANON); /* no echo, signals,
or erase/kill processing */
#endif
nttyjunk.c_cc[VMIN] = 1; /* return after every character read */
nttyjunk.c_cc[VTIME] = 1;
ttywarp = charms[ttyjunk.c_cflag&CBAUD]; /* milliseconds for character */
ioctl(1, TCSETAW, &nttyjunk);
ioctl(1, TCXONC,1); /* Force tty back on */
#else
struct sgttyb nttyjunk;
gtty (1,&ttyjunk);
nttyjunk=ttyjunk;
nttyjunk.sg_flags &= (~ECHO); /* it was so SIMPLE in the old days */
nttyjunk.sg_flags |= (RAW);
ttywarp = charms[ttyjunk.sg_ospeed]; /* milliseconds for char */
stty(1,&nttyjunk);
#endif
#ifndef RT
ttyerase = ttyjunk.c_cc[VERASE];
ttykill = ttyjunk.c_cc[VKILL];
ttyeof = ttyjunk.c_cc[VEOF];
ttyintr = ttyjunk.c_cc[VINTR];
#else
ttyerase = ttyjunk.sg_erase;
ttykill = ttyjunk.sg_kill;
ttyeof = '\004';
ttyintr = '';
#endif
if (VEXIT) eprintf(SCINIT); /* RE-init terminal */
}
/* out of raw mode */
cook()
{
if (VEXIT) eprintf(VEXIT);
fflush(stdout); /* force output */
#ifdef ux3
ioctl(1,TCSETAW, &ttyjunk);
ioctl(1, TCXONC,1); /* Force tty back on */
#else
stty(1,&ttyjunk);
#endif
}
/*VARARGS2*/
char *
nscan(stptr,ret)
register char *stptr;
register int *ret;
{
register c;
*ret = 0;
while (((c = *stptr)>='0') && (c <= '9')) {
stptr++;
*ret = *ret*10+(c-'0');
}
return(stptr);
}
char *
strcpy(cp,cp1)
register char *cp;
register char *cp1;
{
while (*cp++ = *cp1++);
return(cp-1);
}
seprintf(string,fmt, x1)
register char *string;
register char *fmt;
unsigned x1;
{
int c;
int width;
register unsigned int *adx;
extern char *strcpy();
adx = &x1;
loop:
while((c = *fmt++) != '%') {
*string++ = c;
if(c == '\0') {
return;
}
}
width = 0;
c = *fmt++;
if ((c >= '0') && (c <= '9')) {
fmt = nscan(fmt-1,&width);
c = *fmt++;
}
switch(c) {
case 'd':
case 'D':
case 'o':
case 'O':
{
register int b;
long n;
long n1;
register int i;
char dstack[20];
b = (((c=='o') || (c == 'O'))? 8: 10); /* number base */
if ((c == 'o') || (c == 'd')) {
n = (long) (*adx);
if (n > 32768L) n = n-65536L; /* sign correction */
} else {
n = *((long *) adx);
adx += ((sizeof(n)-sizeof(i))/sizeof(i));
}
i = 0;
if (n < 0) {
n = -n;
*string++ = '-';
}
do {
n1 = n/b;
dstack[i++] = (short) (n-(n1*b));
n = n1;
} while (n != 0); /* figure number */
if ((b == 8) && ((i !=1 ) || (dstack[0] != 0))) dstack[i++]=0;
while (i<width) dstack[i++] = 0;
while (i > 0) *string++ =(dstack[--i] + '0'); /* print number */
}
break;
case 'P':
width *= SREGION;
/* Fall through */
case 'p':
while (width > 0) {
*string++ = *NOP;
width -= ttywarp;
}
adx--;
break;
case 's':
string = strcpy(string,(char *)*adx);
break;
case 'm':
case 'M':
{
char *cp;
if (c=='m') {
cp = &TMAP[width * (*adx)];
} else {
cp = &SMAP[width * (*adx)];
}
for (c = 0; c < width; c++) {
if (*cp) *string++ = *cp++;
}
}
break;
case 'c':
c = *adx;
if (c) {
*string++ = c;
} else {
*string++ = '^';
*string++ = '@'; /* punt */
}
break;
case '%':
*string++ ='%';
adx--;
break;
default:
break;
}
adx++;
goto loop;
}
mgetchar()
{
fflush(stdout); /* force output */
return(0177 & getchar());
}
/*VARARGS1*/
eprintf(string,a1,a2,a3,a4,a5,a6,a7)
register char *string;
{
char pbuf[1024];
seprintf(pbuf,string,a1,a2,a3,a4,a5,a6,a7);
PUTS(pbuf);
}
xprintf(sp,ap1,ap2,ap3,ap4,ap5,ap6)
register char *sp;
{
char sbuf[0400]; /* buffer */
register c;
int x;
sprintf(sbuf,sp,ap1,ap2,ap3,ap4,ap5,ap6);
sp = sbuf;
while (c = *sp++) {
if (c == '\n') {
clrl();
if (++mline >= ECHOL) {
mline=0;
}
mcol=0;
} else {
xputc(c);
}
}
}
die(arg)
int arg;
{
mgo(SCRNLIN-1,0);
clrl();
cook();
if (arg) abort(arg);
else exit(0);
}
ttystart()
{
int i;
char *tp;
setbuf(stdout,ttobuf);
uncook();
for (i = 0; i < 16; i++) {
signal(i,die);
}
tp = getenv("TERM");
if (tp == NULL) ttype();
else sttype(tp);
}
insrtc(c)
int c;
{
if (INSERTC == NULL) return(0);
INSON = 1;
ldchar = c;
ldcol = mcol-1;
mputc(c);
INSON = 0;
return(1);
}
delc()
{
register i;
if (DELC == NULL) return(0);
SREGION=scrjnk[mline]-mcol; /* number of char's gobbled */
if (DELMODE && (osert == 0)) {
eprintf(INSERTM);
osert++;
}
eprintf(DELC); /*clobber next char */
for (i = mcol; i <=scrjnk[mline];i++) {
cmap[mline] [i] = cmap[mline] [i+1];
}
scrjnk[mline]--;
return(1);
}
/* adjust vertical position of line -- open (or close) lines on */
/* the screen argument is the number of lines to add (or drop). */
vadjust(xline,tline,x)
register x;
int xline;
int tline;
{
register i;
register j;
int oldx;
if (LOPEN == NULL) return(0);
oldx = xline;
if (x<0) {
x = -x;
i = 1;
} else i = 0;
SREGION=tline-oldx; /* effected region */
if (i) { /* if deleting lines */
sgo(xline,0);
if (SCREG) { /*if vt100 stype scrolling */
eprintf(SCREG,oldx+XBASE,tline+XBASE); /*define region*/
scrlin = scrcol = 0;
sgo(tline,0);
for (i = 0; i < x; i ++) {
eprintf(SSCROLL);
}
eprintf(SCREG,XBASE,SCRNLIN);
scrlin = scrcol = 0;
} else {
for (i = 0; i < x; i++) {
eprintf(LDEL);
}
sgo(tline-x+1,0);
for (i = 0; i < x; i++) {
eprintf(LOPEN);
}
}
sgo(oldx,0);
vshift (oldx,tline,x);
} else {
if (SCREG) { /* if vt100 style scrolling */
eprintf(SCREG,oldx+XBASE,tline+XBASE); /*define region */
scrlin = scrcol = 0; /* vt100 dies */
sgo(xline,0);
for (i = 0; i < x; i ++) {
eprintf(RSCROLL);
}
eprintf(SCREG,XBASE,SCRNLIN);
scrlin = scrcol = 0;
} else {
sgo(tline+1-x,0);
for (i = 0; i < x;i++) eprintf(LDEL);
sgo(oldx,0);
for (i = 0; i < x; i++) eprintf(LOPEN);
}
mgo(oldx,0);
vshift(oldx,tline,-x);
}
return(1);
}
/* sscroll -- try to fix display by scrolling */
sscroll(x)
register int x;
{
register int i;
if (SSCROLL == NULL) return(0);
sgo(SCRNLIN-1,0); /* to bottom */
SREGION=SCRNLIN; /* number of lines effected */
for (i = 0; i < x; i++) {
eprintf(SSCROLL); /* scroll screen */
}
vshift (0,SCRNLIN-1,x);
}
/* vshift -- shift the display image from top to bottom (inclusive) by x */
vshift(top,bottom,x)
int top;
int bottom;
int x;
{
register i;
register j;
char *cp1;
char *cp2;
int *jnkptr;
int start;
int stop;
register int off;
if (x > 0) {
off = 1;
start = top;
stop = bottom+1;
} else {
off = -1;
start = bottom;
stop = top-1;
}
for (i = start,jnkptr = scrjnk+i; i != stop-x; i+=off,jnkptr+=off) {
*jnkptr = *(jnkptr+x);
cp1 = cmap[i];
cp2 = cmap[i+x];
for (j = 0; j < *jnkptr; j++) {
*cp1++ = *cp2++;
}
}
while (i != stop) {
if (off > 0) {
*jnkptr++ = 0;
i++;
} else {
*jnkptr-- = 0;
i--;
}
}
}
/* print an underscored character. */
pu(c)
register char c;
{
register oc;
c &= 0177;
if ((c == 0)||(c == 040)) {
/* bare underscore */
putchar('_');
return; /* just put out the underscore */
}
if (UEND == 0) {
eprintf(ULINE,c);
} else {
eprintf(ULINE); /* enter "underscore mode" */
putchar(c);
eprintf(UEND);
}
}
putit(c)
char c;
{
if (drain) return;
if (c & 0200) {
pu(c);
return;
}
putchar(0177 & c);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.