v08i005: Georgia Tech 'se' Screen Editor
sources-request at mirror.UUCP
sources-request at mirror.UUCP
Tue Jan 27 07:20:09 AEST 1987
Submitted by: emoryu1!arnold (Arnold D. Robbins)
Mod.sources: Volume 8, Issue 5
Archive-name: se/Part05
Here is the second release of the Georgia Tech Screen Editor, 'se'.
There were enough changes that a whole new posting is warranted.
Major Changes:
All Georgia Tech specific stuff removed.
It understands window size changes on 4.3BSD and ATT Unix PC/3B1
Support for the shared library on the ATT Unix PC/3B1
Considerable source code reorganization in certain files.
Enjoy,
Arnold Robbins
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# term.c
# libchangetty
# pat
export PATH; PATH=/bin:$PATH
echo shar: extracting "'term.c'" '(37533 characters)'
if test -f 'term.c'
then
echo shar: will not over-write existing file "'term.c'"
else
cat << \SHAR_EOF > 'term.c'
#ifndef lint
static char RCSid[] = "$Header: term.c,v 1.7 86/11/12 11:37:30 arnold Exp $";
#endif
/*
* $Log: term.c,v $
* Revision 1.7 86/11/12 11:37:30 arnold
* Fixed winsize() to verify that cols and rows not 0 before assigning
* them to Nrows and Ncols.
*
* Revision 1.6 86/10/14 11:10:36 arnold
* Reorganization of window handling stuff. Added (untested) code for sun.
*
* Revision 1.5 86/10/07 14:50:48 arnold
* Changed setterm to set_term, to avoid Unix/PC shared library conflict.
* Fixed winsize() to set Nrows and Ncols on first call, as well.
*
* Revision 1.4 86/09/19 12:15:28 arnold
* Fixes to BSD windowing for real 4.3, from BRL.
*
* Revision 1.3 86/07/17 17:23:19 arnold
* Massive reorganization and cleaning up. Terminal initialization
* stuff moved here, and homogenized.
*
* Revision 1.2 86/07/14 17:19:33 arnold
* Added code that notices whether or not the window we are runnng in has
* changed sizes. It definitely works on the Unix PC, and should work on
* BRL Unix and 4.3 BSD.
*
* Revision 1.1 86/05/06 13:38:53 osadr
* Initial revision
*
*
*/
/*
** term.c
**
** provide terminal functions for se
**
** If HARD_TERMS is *not* defined, which is the default, se will
** use the termlib library, which provides terminal independant operations.
** This makes se both smaller, and more flexible.
**
** If HARD_TERMS is defined, then se will use the original code, which
** had terminal types hard-wired into the code. This would be useful for
** a system which does not have the termlib library.
**
** On System V systems, we have two possibilities. Release 1 did not have
** the terminfo package, so we assume that if it is Release 1, someone will
** have ported the BSD termlib library. If it is Release 2, then the new
** terminfo package is there, and we wil use it.
**
** This file is large. It is organized as follows.
**
** Routines that do not care whether or not HARD_TERMS is defined.
** Routines that are only if HARD_TERMS is NOT defined. These contain:
** BSD/termlib routines
** System V/terminfo routines
** Routines idenpendant of BSD/System V
** Routines that are only if HARD_TERMS is defined.
** Routines that have regular and conditonal code mixed.
*/
#include "se.h"
#include "extern.h"
/* outc -- write a character to the terminal */
int outc (c)
char c;
{
twrite (1, &c, 1);
}
#ifndef HARD_TERMS
#if defined (BSD) || !defined (S5R2)
/*
* code for using BSD termlib -- getting capabilities, and writing them out.
*/
/* capabilities from termcap */
static int AM; /* automatic margins, i.e. wraps at column 80 */
static char *VS; /* visual start -- e.g. clear status line */
static char *VE; /* visual end -- e.g. restore status line */
static char *TI; /* terminal init -- whatever needed for screen ops */
static char *TE; /* terminal ops end */
static char *CM; /* cursor motion, used by tgoto() */
static char *CE; /* clear to end of line */
static char *DL; /* hardware delete line */
static char *AL; /* hardware add (insert) line */
static char *CL; /* clear screen */
extern char PC; /* Pad character, usually '\0' */
static char *pcstr;
extern char *tgoto (), *tgetstr (); /* termlib routines */
static char caps[128]; /* space for decoded capability strings */
static char *addr_caps; /* address of caps for relocation */
#define TERMBUFSIZ 1024+1
static char termbuf[TERMBUFSIZ];
/* getdescrip --- get descriptions out of termcap entry */
static getdescrip ()
{
int i;
static struct _table {
char *name;
char **ptr_to_cap;
} table[] = {
"vs", & VS,
"ve", & VE,
"ti", & TI,
"te", & TE,
"cm", & CM,
"ce", & CE,
"dl", & DL,
"al", & AL,
"cl", & CL,
"pc", & pcstr,
NULL, NULL
};
AM = tgetflag ("am"); /* only boolean se needs */
/* get string values */
for (i = 0; table[i].name != NULL; i++)
*(table[i].ptr_to_cap) = tgetstr (table[i].name, & addr_caps);
}
/* setcaps -- get the capabilities from termcap file into termbuf */
static setcaps (term)
char *term;
{
switch (tgetent (termbuf, term)) {
case -1:
error (NO, "se: couldn't open termcap file.");
case 0:
error (NO, "se: no termcap entry for %s terminals.", term);
case 1:
addr_caps = caps;
getdescrip (); /* get terminal description */
Nrows = tgetnum ("li");
Ncols = tgetnum ("co");
break;
default:
error (YES, "in setcaps: can't happen.\n");
}
return (OK);
}
#else
/* use the new terminfo package */
/*
* Do NOT include <curses.h>, since it redefines
* USG, ERR, and OK, to values inconsistent with what
* we use.
*/
/* fix a problem in /usr/include/term.h */
#include <termio.h>
typedef struct termio SGTTY;
#include <term.h> /* should be all we really need */
#define AM auto_right_margin
#define TI enter_ca_mode
#define TE exit_ca_mode
#define VS cursor_visible
#define VE cursor_normal
#define CL clear_screen
#define CE clr_eol
#define DL delete_line
#define AL insert_line
/* setcaps -- get the capabilities from the terminfo database */
static setcaps (term)
char *term;
{
int ret = 0;
setupterm (term, 1, & ret);
if (ret != 1)
return (ERR);
Nrows = lines;
Ncols = columns;
return (OK);
}
#endif
/* t_init -- put out terminal initialization string */
t_init ()
{
if (VS)
tputs (VS, 1, outc);
if (TI)
tputs (TI, 1, outc); /* terminal initializations */
}
/* t_exit -- put out strings to turn off whatever modes we had turned on */
t_exit ()
{
/* terminal exiting strings */
if (TE)
tputs (TE, 1, outc);
if (VE)
tputs (VE, 1, outc);
tflush (); /* force it out */
}
/* winsize --- get the size of the window from the windowing system */
/* also arrange to catch the windowing signal */
#include <signal.h>
#ifdef SIGWIND /* UNIX PC */
#include <sys/font.h>
#include <sys/window.h>
#define WINSIG SIGWIND
#define WINIOCTL WIOCGETD
#define WINSTRUCT uwdata
#define COLS (w.uw_width / w.uw_hs)
#define ROWS (w.uw_height / w.uw_vs)
#endif
#ifdef SIGWINCH /* 4.3 BSD and/or Sun 3.x */
#define WINSIG SIGWINCH
#ifdef sun
#undef NEWLINE /* shouldn't hurt; these are in sun include files */
#undef TAB
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/tty.h>
#define WINIOCTL TIOCGSIZE
#define WINSTRUCT ttysize
#define COLS w.ts_cols
#define ROWS w.ts_lines
#else
#include <sys/ioctl.h>
#define WINIOCTL TIOCGWINSZ
#define WINSTRUCT winsize
#define COLS w.ws_col
#define ROWS w.ws_row
#endif
#endif
static struct WINSTRUCT w;
winsize ()
{
#if defined(SIGWIND) || defined(SIGWINCH)
static int first = 1;
static char savestatus[MAXCOLS];
int row, oldstatus = Nrows - 1;
int cols, rows;
signal (WINSIG, winsize);
if (ioctl (0, WINIOCTL, (char *) & w) != -1)
{
cols = COLS;
rows = ROWS;
if (first)
{
first = 0;
if (cols && rows)
{
Ncols = cols;
Nrows = rows;
}
return; /* don't redraw screen */
}
else if (Ncols == cols && Nrows == rows)
{
/* only position changed */
#ifdef SIGWIND
remark ("window repositioned");
#endif
return;
}
else
{
if (cols && rows)
{
Ncols = cols;
Nrows = rows;
}
}
}
else
return;
move_ (Screen_image[oldstatus], savestatus, MAXCOLS);
clrscreen ();
Toprow = 0;
Botrow = Nrows - 3;
Cmdrow = Botrow + 1;
Sclen = -1;
for (row = 0; row < Nrows; row++)
move_ (Blanks, Screen_image[row], MAXCOLS);
/* clear screen */
First_affected = Topln;
adjust_window (Curln, Curln);
updscreen (); /* reload from buffer */
loadstr (savestatus, Nrows - 1, 0, Ncols);
remark ("window size change");
tflush ();
#endif
}
#else
/* begin terminal dependant routines */
/* addspos --- position cursor to (row, col) on ADDS Consul 980 */
static addspos (row, col)
int row, col;
{
char coord;
int ntabs, where;
if (Currow != row || col < Curcol - 7)
{
twrite (1, "\013", 1); /* VT */
coord = '@' + row;
twrite (1, &coord, 1);
Currow = row;
Curcol = 0;
}
if (col > Curcol + 2)
{
ntabs = (col + 2) / 5; /* from beginning */
where = ntabs * 5;
ntabs -= Curcol / 5; /* from Curcol */
if (ntabs + abs (where - col) <= 4)
{
for (; ntabs > 0; ntabs--)
twrite (1, "\t", 1);
Curcol = where;
}
}
if (col > Curcol + 4)
{
where = col - Curcol;
twrite (1, "\033\005", 2); /* ESC ENQ */
coord = '0' + (where / 10);
twrite (1, &coord, 1);
coord = '0' + (where % 10);
twrite (1, &coord, 1);
Curcol = col;
}
while (Curcol < col)
{
twrite (1, &Screen_image[Currow][Curcol], 1);
Curcol++;
}
while (Curcol > col)
{
twrite (1, "\b", 1);
Curcol--;
}
}
/* admpos --- position cursor to (row, col) on ADM-3A and ADM-31 terminals */
static admpos (row, col)
int row, col;
{
int dist;
char coord;
dist = col - Curcol;
if (dist < 0)
dist = -dist;
if (row == Currow && dist < 4) /* 4 chars for abs. position */
{
while (Curcol < col)
{
twrite (1, &Screen_image[Currow][Curcol], 1);
Curcol++;
}
while (Curcol > col)
{
twrite (1, "\b", 1);
Curcol--;
}
}
else
{
twrite (1, "\033=", 2);
coord = row + ' ';
twrite (1, &coord, 1);
coord = col + ' ';
twrite (1, &coord, 1);
Currow = row;
Curcol = col;
}
}
/* ansipos --- position cursor on ANSI X something-or-other terminals */
static ansipos (row, col)
register int row, col;
{
register int dist;
char absseq[20], relseq[50];
int absp = 0;
register int relp = 0;
register int trow, tcol;
/*** Build relative positioning string--handle row first ***/
trow = Currow;
tcol = Curcol;
if (row >= trow && row <= trow + 3)
for (; trow < row; trow++)
relseq[relp++] = '\012';
else if (row < trow && row >= trow - 1)
for (; trow > row; trow--)
{
relseq[relp++] = '\033';
relseq[relp++] = 'M';
}
else if (row >= trow)
{
relseq[relp++] = '\033';
relseq[relp++] = '[';
dist = row - trow;
if (dist >= 10)
relseq[relp++] = '0' + dist / 10;
relseq[relp++] = '0' + dist % 10;
relseq[relp++] = 'B';
trow = row;
}
else /* row < trow */
{
relseq[relp++] = '\033';
relseq[relp++] = '[';
dist = trow - row;
if (dist >= 10)
relseq[relp++] = '0' + dist / 10;
relseq[relp++] = '0' + dist % 10;
relseq[relp++] = 'A';
trow = row;
}
/*** Now do the column part of relative positioning ***/
if (col >= tcol - 2 && col <= tcol + 2)
; /* skip coarse positioning -- just do the fine stuff */
else
{
if (col <= 4)
{
relseq[relp++] = '\015';
tcol = 0;
}
dist = col - tcol;
if (col < 72 && dist > 2
&& dist < 8 && (col + 1) % 8 <= 2)
{
relseq[relp++] = '\t';
tcol = ((tcol + 8) / 8) * 8;
}
}
dist = col - tcol;
if (dist < 0)
dist = -dist;
if (dist == 0)
;
else if (dist < 4) /* 4 chars for abs. position */
{
while (tcol < col)
{
relseq[relp++] = Screen_image[trow][tcol];
tcol++;
}
while (tcol > col)
{
relseq[relp++] = '\b';
tcol--;
}
}
else if (col >= tcol)
{
relseq[relp++] = '\033';
relseq[relp++] = '[';
if (dist >= 10)
relseq[relp++] = '0' + dist / 10;
relseq[relp++] = '0' + dist % 10;
relseq[relp++] = 'C';
tcol = col;
}
else /* if (col < tcol) */
{
relseq[relp++] = '\033';
relseq[relp++] = '[';
if (dist >= 10)
relseq[relp++] = '0' + dist / 10;
relseq[relp++] = '0' + dist % 10;
relseq[relp++] = 'D';
tcol = col;
}
/*** If relative positioning will do it, forget absolute ***/
if (relp <= 5)
twrite (1, relseq, relp);
else
{
absseq[absp++] = '\033';
absseq[absp++] = '[';
if (row >= 9)
absseq[absp++] = '0' + (row + 1) / 10;
absseq[absp++] = '0' + (row + 1) % 10;
absseq[absp++] = ';';
if (col >= 9)
absseq[absp++] = '0' + (col + 1) / 10;
absseq[absp++] = '0' + (col + 1) % 10;
absseq[absp++] = 'H';
if (absp >= relp)
twrite (1, relseq, relp);
else
twrite (1, absseq, absp);
}
Curcol = col;
Currow = row;
}
/* anppos --- position cursor on Allen & Paul model 1 */
static anppos (row, col)
int row, col;
{
char coord;
if (row == Currow) /* if close, just sneak right or left */
{
if (col == Curcol + 1)
twrite (1, "\t", 1);
else if (col == Curcol + 2)
twrite (1, "\t\t", 2);
else if (col == Curcol - 1)
twrite (1, "\b", 1);
else if (col == Curcol - 2)
twrite (1, "\b\b", 2);
else
{
twrite (1, "\033C", 2);
coord = col + ' ';
twrite (1, &coord, 1);
}
}
else if (col == Curcol) /* if close, sneak up or down */
{
if (row == Currow + 1)
twrite (1, "\012", 1);
else if (row == Currow + 2)
twrite (1, "\012\012", 2);
else if (row == Currow - 1)
twrite (1, "\013", 1);
else if (row == Currow - 2)
twrite (1, "\013\013", 2);
else
{
/* because of bug in anp software, abs row pos is not working.
* the following code was replaced to compensate:
*
* twrite (1, "\033R", 2);
* coord = row + ' ';
* twrite (1, &coord, 1);
*/
twrite (1, "\033P", 2);
coord = row + ' ';
twrite (1, &coord, 1);
coord = col + ' ';
twrite (1, &coord, 1);
}
}
else /* resort to absolute positioning */
{
twrite (1, "\033P", 2);
coord = row + ' ';
twrite (1, &coord, 1);
coord = col + ' ';
twrite (1, &coord, 1);
}
Currow = row;
Curcol = col;
}
/* b200coord --- transmit a coordinate for Beehive 200 cursor addressing */
static b200coord (coord)
int coord;
{
char acc;
int tens, units;
tens = coord / 10;
units = coord - 10 * tens;
acc = units + 16 * tens;
twrite (1, & acc, 1);
}
/* beepos --- position cursor on Beehive terminal */
static beepos (row, col)
int row, col;
{
if (row == Currow + 1 && col == 0 && Term_type != SBEE)
{
twrite (1, "\r\n", 2); /* CR LF */
Curcol = 0;
Currow++;
}
else if (row == 0 && col == 0) /* home cursor */
{
twrite (1, "\033H", 2);
Currow = Curcol = 0;
}
else if (row == Currow && col > Curcol && col <= Curcol + 4)
while (Curcol != col)
{
twrite (1, &Screen_image[Currow][Curcol], 1);
Curcol++;
}
else if (row == Currow && col < Curcol && col >= Curcol - 4)
while (Curcol != col)
{
twrite (1, "\b", 1);
Curcol--;
}
else /* resort to absolute addressing */
{
twrite (1, "\033F", 2);
if (Term_type == BEE200 || Term_type == SOL)
{
b200coord (row);
b200coord (col);
}
else if (Term_type == BEE150)
{
char r, c;
r = row + ' ';
c = col + ' ';
twrite (1, &r, 1);
twrite (1, &c, 1);
}
else /* is superbee */
{
sbeecoord (col);
sbeecoord (row);
}
Currow = row;
Curcol = col;
}
}
/* cgpos --- position cursor on Chromatics CG */
static cgpos (row, col)
int row, col;
{
char i, j;
if (row == Currow + 1 && col == 0)
{
twrite (1, "\r\n", 2); /* CR LF */
Curcol = 0;
Currow++;
}
else if (row == 0 && col == 0) /* home cursor */
{
twrite (1, "\034", 1); /* FS */
Currow = Curcol = 0;
}
else if (row == Currow && col > Curcol && col <= Curcol + 7)
while (Curcol != col)
{
twrite (1, "\035", 1); /* GS */
Curcol++;
}
else if (row == Currow && col < Curcol && col >= Curcol - 7)
while (Curcol != col)
{
twrite (1, "\b", 1);
Curcol--;
}
else
{
/* resort to absolute addressing */
twrite (1, "\001U", 2); /* SOH U */
i = 511 - (10 * row);
j = 6 * col;
cgcoord (j);
cgcoord (i);
Currow = row;
Curcol = col;
}
}
/* cgcoord --- output a decimal coordinate for Chromatics CG */
static cgcoord (i)
int i;
{
int units, tens, hundreds;
char coords[4];
units = i % 10;
i /= 10;
tens = i % 10;
i /= 10;
hundreds = i % 10;
coords[0] = hundreds + 16 + ' ';
coords[1] = tens + 16 + ' ';
coords[2] = units + 16 + ' ';
coords[3] = EOS;
twrite (1, coords, 3);
}
/* gt40pos --- position cursor to (row, col) on DEC GT40 with Waugh software */
static gt40pos (row, col)
int row, col;
{
char coord;
if (row != Currow && col != Curcol) /* absolute positioning */
{
twrite (1, "\033", 1);
coord = row + ' ';
twrite (1, &coord, 1);
coord = col + ' ';
twrite (1, &coord, 1);
Currow = row;
Curcol = col;
}
else if (row != Currow) /* col must = Curcol */
{ /* vertical positioning */
twrite (1, "\006", 1); /* ACK */
coord = row + ' ';
twrite (1, &coord, 1);
Currow = row;
}
else if (abs (col - Curcol) < 2)
uhcm (col);
else
{
twrite (1, "\025", 1); /* NACK */
coord = col + ' ';
twrite (1, &coord, 1);
Curcol = col;
}
}
/* h19pos --- position cursor on Heath H19 (DEC VT52 compatible, supposedly) */
static h19pos (row, col)
int row, col;
{
int dist;
char coord;
dist = col - Curcol;
if (dist < 0)
dist = -dist;
if (row == Currow && dist < 4) /* 4 chars for abs. position */
{
while (Curcol < col)
{
twrite (1, &Screen_image[Currow][Curcol], 1);
Curcol++;
}
while (Curcol > col)
{
twrite (1, "\b", 1);
Curcol--;
}
}
else
{
twrite (1, "\033Y", 2);
coord = row + ' ';
twrite (1, &coord, 1);
coord = col + ' ';
twrite (1, &coord, 1);
Currow = row;
Curcol = col;
}
}
/* hp21pos --- position cursor on HP 2621 terminal */
static hp21pos (row, col)
int row, col;
{
int units, tens;
if (row == Currow && col == 0)
{
twrite (1, "\r\n", 2); /* CR LF */
Curcol = 0;
Currow++;
}
else if (row == 0 && col == 0) /* home cursor */
{
twrite (1, "\033H", 2);
Currow = Curcol = 0;
}
else if (row == Currow && col > Curcol && col <= Curcol + 4)
while (Curcol != col)
{
twrite (1, &Screen_image[Currow][Curcol], 1);
Curcol++;
}
else if (row == Currow && col < Curcol && col >= Curcol - 4)
while (Curcol != col)
{
twrite (1, "\b", 1);
Curcol--;
}
else if (2 * abs (Currow - row) + abs (Curcol - col) <= 7)
{
while (Currow < row)
{
twrite (1, "\033B", 2);
Currow++;
}
while (Currow > row)
{
twrite (1, "\033A", 2);
Currow--;
}
while (Curcol > col)
{
twrite (1, "\b", 1);
Curcol--;
}
while (Curcol < col)
{
twrite (1, & Screen_image[Currow][Curcol], 1);
Curcol++;
}
}
else
{
/* resort to absolute addressing */
char c;
twrite (1, "\033&a", 3);
units = row % 10;
tens = row / 10;
if (tens != 0)
{
c = tens + '0';
twrite (1, &c, 1);
}
c = units + '0';
twrite (1, &c, 1);
twrite (1, "y", 1);
units = col % 10;
tens = col / 10;
if (tens != 0)
{
c = tens + '0';
twrite (1, &c, 1);
}
c = units + '0';
twrite (1, &c, 1);
twrite (1, "C", 1);
Currow = row;
Curcol = col;
}
}
/* hazpos --- position cursor on Hazeltine 1510 */
static hazpos (row, col)
int row, col;
{
int dist;
char c;
dist = col - Curcol;
if (dist < 0)
dist = -dist;
if (row == Currow && dist < 4) /* 4 chars for abs. position */
{
while (Curcol < col)
{
twrite (1, &Screen_image[Currow][Curcol], 1);
Curcol++;
}
while (Curcol > col)
{
twrite (1, "\b", 1);
Curcol--;
}
}
else
{
twrite (1, "\033\021", 2);
c = col;
twrite (1, &c, 1);
c = row;
twrite (1, &c, 1);
Currow = row;
Curcol = col;
}
}
/* ibmpos --- position cursor on IBM 3101 terminal */
static ibmpos (row, col)
int row, col;
{
int dist;
static char abspos[] = "\033\Y\0\0";
dist = col - Curcol;
if (dist < 0)
dist = -dist;
if (row == Currow && dist < 4) /* 4 chars for abs pos */
{
while (Curcol < col)
{
twrite (1, & Screen_image[Currow][Curcol], 1);
Curcol++;
}
while (Curcol > col)
{
twrite (1, "\b", 1);
Curcol--;
}
}
else
{
abspos[2] = row + ' ';
abspos[3] = col + ' ';
twrite (1, abspos, 4);
Currow = row;
Curcol = col;
}
}
/* iscpos --- position cursor on ISC 8001 color terminal */
static iscpos (row, col)
int row, col;
{
char r, c;
if (row == 0 && col == 0)
twrite (1, "\b", 1);
else
{
twrite (1, "\003", 1); /* ETX */
r = row;
c = col;
twrite (1, & r, 1);
twrite (1, & c, 1);
}
Currow = row;
Curcol = col;
}
/* netpos --- position cursor on Netron terminal */
static netpos (row, col)
int row, col;
{
static char abspos[] = "\033=\0\0";
abspos[2] = (char) row;
abspos[3] = (char) col;
twrite (1, abspos, 4);
Currow = row;
Curcol = col;
}
/* pepos --- position cursor on Perkin-Elmer 550 & 1100 terminals */
static pepos (row, col)
int row, col;
{
char coord;
/* get on correct row first */
if (Currow == row)
; /* already on correct row; nothing to do */
else if (row == Currow - 1)
{
twrite (1, "\033A", 2); /* cursor up */
Currow--;
}
else if (row == Currow + 1)
{
twrite (1, "\033B", 2); /* cursor down */
Currow++;
}
else
{
/* vertical absolute positioning */
twrite (1, "\033X", 2);
coord = row + ' ';
twrite (1, & coord, 1);
}
/* now perform horizontal motion */
if (abs (col - Curcol) > 3) /* do absolute horizontal position */
{
twrite (1, "\033Y", 2);
coord = col + ' ';
twrite (1, &coord, 1);
Curcol = col;
}
else
uhcm (col);
}
/* sbeecoord --- transmit a coordinate for Superbee terminal */
static sbeecoord (coord)
int coord;
{
char r, c;
r = (coord / 10) + ' ';
c = (coord % 10) + ' ';
twrite (1, & r, 1);
twrite (1, & c, 1);
}
/* trspos --- position cursor on TRS80 Model 1 */
static trspos (row, col)
int row, col;
{
while (Currow != row)
{
if (Currow > row)
{
twrite (1, "\033", 1);
Currow--;
}
else
{
twrite (1, "\032", 1); /* SUB */
Currow++;
}
}
if (Curcol != col)
{
if (col > Curcol)
while (col > Curcol)
{
twrite (1, "\031", 1); /* EM */
Curcol++;
}
else if (col < Curcol / 2)
{
twrite (1, "\035", 1); /* GS */
Curcol = 0;
while (Curcol < col)
{
twrite (1, "\031", 1); /* EM */
Curcol++;
}
}
else
while (col < Curcol)
{
twrite (1, "\030", 1); /* CAN */
Curcol--;
}
}
}
/* tvtpos --- position cursor on Allen's TV Typetwriter II */
static tvtpos (row, col)
int row, col;
{
register int horirel, horiabs, vertrel, vertabs;
horirel = col - Curcol;
if (horirel < 0)
horirel = -horirel;
horiabs = col;
if (row <= Currow)
vertrel = Currow - row;
else
vertrel = Nrows - (row - Currow);
if (row == 0)
vertabs = 0;
else
vertabs = Nrows - row;
if (1 + horiabs + vertabs <= horirel + vertrel)
{
twrite (1, "\014", 1);
Currow = Curcol = 0;
}
while (Currow != row)
{
twrite (1, "\013", 1);
Currow--;
if (Currow < 0)
Currow = Nrows - 1;
}
if (Curcol > col)
for (; Curcol != col; Curcol--)
twrite (1, "\b", 1);
else
for (; Curcol != col; Curcol++)
twrite (1, "\t", 1);
}
/* regentpos --- position cursor on ADDS Regent 100 */
static regentpos (row, col)
int row, col;
{
int dist;
char coord;
dist = col - Curcol;
if (dist < 0)
dist = -dist;
if (dist > 4 || Currow != row)
{
twrite (1, "\033Y", 2);
coord = ' ' + row;
twrite (1, &coord, 1);
coord = ' ' + col;
twrite (1, &coord, 1);
Currow = row;
Curcol = col;
}
else
{
while (row < Currow)
{
twrite (1, "\032", 1); /* SUB, cursor up */
Currow--;
}
while (row > Currow)
{
twrite (1, "\n", 1);
Currow++;
Curcol = 1;
}
if (col > Curcol)
while (col != Curcol)
{
twrite (1, &Screen_image[Currow][Curcol], 1);
Curcol++;
}
else if ((Curcol - col) * 2 >= Ncols)
while (col != Curcol)
{
twrite (1, "\006", 1); /* ACK, cursor right */
if (Curcol == Ncols)
Curcol = 1;
else
Curcol++;
}
else
while (col != Curcol)
{
twrite (1, "\b", 1);
Curcol--;
}
}
}
/* vipos --- position cursor on Visual 200 & 50 */
static vipos (row, col)
register int row, col;
{
register int dist;
register char coord;
if (row == Currow + 1 && col < 3)
{
twrite (1, "\015\012", 2);
Currow++;
Curcol = 0;
}
dist = col - Curcol;
if (Term_type == VI200 && row == Currow && col < 72 && dist > 2
&& dist < 8 && (col + 1) % 8 < 2)
{
twrite (1, "\t", 1);
Curcol = ((Curcol + 7) / 8) * 8;
dist = col - Curcol;
}
if (dist < 0)
dist = -dist;
if (row == Currow && dist < 4) /* 4 chars for abs. position */
{
while (Curcol < col)
{
twrite (1, &Screen_image[Currow][Curcol], 1);
Curcol++;
}
while (Curcol > col)
{
twrite (1, "\b", 1);
Curcol--;
}
}
else
{
twrite (1, "\033Y", 2);
coord = row + ' ';
twrite (1, &coord, 1);
coord = col + ' ';
twrite (1, &coord, 1);
Currow = row;
Curcol = col;
}
}
/* vcpos --- position cursor Volker-Craig 4404 (ADM3A mode) */
static vcpos (row, col)
int row, col;
{
int dist;
char coord;
dist = col - Curcol;
if (dist < 0)
dist = -dist;
if (row == Currow && dist < 4) /* 4 chars for abs. position */
{
while (Curcol < col)
{
twrite (1, &Screen_image[Currow][Curcol], 1);
Curcol++;
}
while (Curcol > col)
{
twrite (1, "\b", 1);
Curcol--;
}
}
else
{
twrite (1, "\033=", 2);
coord = row + ' ';
twrite (1, &coord, 1);
coord = col + ' ';
twrite (1, &coord, 1);
Currow = row;
Curcol = col;
}
}
/* espritpos --- position cursor on Hazeltine Esprit */
static espritpos (row, col)
int row, col;
{
int dist;
char c;
dist = col - Curcol;
if (dist < 0)
dist = -dist;
if (row == Currow && dist < 4) /* 4 chars for abs. position */
{
while (Curcol < col)
{
twrite (1, &Screen_image[Currow][Curcol], 1);
Curcol++;
}
while (Curcol > col)
{
twrite (1, "\b", 1);
Curcol--;
}
}
else
{
twrite (1, "\033\021", 2);
c = col >= 32 ? col : col + '`';
twrite (1, &c, 1);
c = row >= 32 ? row : row + '`';
twrite (1, &c, 1);
Currow = row;
Curcol = col;
}
}
/* uhcm --- universal horizontal cursor motion */
static uhcm (col)
int col;
{
while (Curcol < col)
{
twrite (1, &Screen_image[Currow][Curcol], 1);
Curcol++;
}
while (Curcol > col)
{
twrite (1, "\b", 1);
Curcol--;
}
}
/* senddelay --- send NULs to delay n milliseconds */
senddelay (n)
int n;
{
register int q;
q = (long) n * Tspeed / 1000l;
while (q > 0)
{
twrite (1, "\0\0\0\0\0\0\0\0\0\0", q > 10 ? 10 : q);
q -= 10;
}
}
/* decode_mnemonic --- decode a terminal type mnemonic */
static int decode_mnemonic (str)
char str[];
{
int i;
int strbsr ();
static struct {
char *s;
int t;
} stab[] = {
"950", TVI950,
"adm31", ADM31,
"adm3a", ADM3A,
"anp", ANP,
"b150", BEE150,
"b200", BEE200,
"cg", CG,
"consul", ADDS980,
"esprit", ESPRIT,
"fox", FOX,
"gt40", GT40,
"h19", H19,
"haz", HAZ1510,
"hp21", HP21,
"hz1510", HAZ1510,
"ibm", IBM,
"isc", ISC8001,
"netron", NETRON,
"regent", ADDS100,
"regent40", ADDS100, /* kludge */
"sbee", SBEE,
"sol", SOL,
"trs80", TRS80,
"ts1", TS1,
"tvt", TVT,
"vc4404", VC4404,
"vi200", VI200,
"vi300", VI300,
"vi50", VI50,
};
i = strbsr ((char *)stab, sizeof (stab), sizeof (stab[0]), str);
if (i == EOF)
return (ERR);
else
return (stab[i].t);
}
#endif
/* terminal handling functions used throughout the editor */
/* send --- send a printable character, predict cursor position */
send (chr)
char chr;
{
if (Currow == Nrows - 1 && Curcol == Ncols - 1)
return; /* anything in corner causes scroll... */
#ifndef HARD_TERMS
outc (chr);
#else
twrite (1, &chr, 1);
#endif
if (Curcol == Ncols - 1)
{
#ifndef HARD_TERMS
if (AM) /* terminal wraps when hits last column */
#else
if (Term_type != TVT && Term_type != NETRON
&& Term_type != ESPRIT && Term_type != VI300)
#endif
{
Curcol = 0;
Currow++;
}
}
else /* cursor not at extreme right */
Curcol++;
}
/* clrscreen --- clear entire screen */
clrscreen ()
{
Curcol = Currow = 0;
/* clearing screen homes cursor to upper left corner */
/* on all terminals */
#ifndef HARD_TERMS
tputs (CL, 1, outc);
#else
switch (Term_type) {
case ADDS980:
case ADDS100:
case GT40:
case CG:
case ISC8001:
case ANP:
case NETRON:
twrite (1, "\014", 1);
break;
case FOX:
twrite (1, "\033K", 2); /* clear display and all tabs */
break;
case TVT:
twrite (1, "\014\017", 2); /* home, erase to end of screen */
break;
case BEE150:
case BEE200:
case SBEE:
case SOL:
case H19:
twrite (1, "\033E", 2);
break;
case HAZ1510:
case ESPRIT:
twrite (1, "\033\034", 2);
break;
case ADM3A:
case VC4404:
case TVI950:
twrite (1, "\032", 1);
break;
case TS1:
twrite (1, "\033*", 2);
break;
case ADM31:
twrite (1, "\033+", 2);
break;
case IBM:
twrite (1, "\033L", 2);
break;
case HP21:
twrite (1, "\033H\033J", 4); /* home cursor, erase to end of screen */
break;
case TRS80:
twrite (1, "\034\037", 2);
break;
case VI200:
twrite (1, "\033v", 2);
break;
case VI300:
twrite (1, "\033[H\033[J", 6);
/* home cursor, clear screen */
break;
case VI50:
twrite (1, "\033v", 2);
senddelay (30);
break;
}
senddelay (20);
#endif
}
/* position_cursor --- position terminal's cursor to (row, col) */
position_cursor (row, col)
int row, col;
{
if (row < Nrows && row >= 0 /* within vertical range? */
&& col < Ncols && col >= 0 /* within horizontal range? */
&& (row != Currow || col != Curcol))/* not already there? */
#ifndef HARD_TERMS
{
if (row == Currow && abs (Curcol - col) <= 4)
{
/* short motion in current line */
if (Curcol < col)
for (; Curcol != col; Curcol++)
twrite (1, &Screen_image[Currow][Curcol], 1);
else
for (; Curcol != col; Curcol--)
twrite (1, "\b", 1);
}
else
{
#if defined (USG) && defined(S5R2)
tputs (tparm (cursor_address, row, col), 1, outc);
#else
tputs (tgoto (CM, col, row), 1, outc);
#endif
Currow = row;
Curcol = col;
}
}
#else
switch (Term_type) {
case ADDS980:
addspos (row, col);
break;
case ADDS100:
regentpos (row, col);
break;
case HP21:
hp21pos (row, col);
break;
case FOX:
pepos (row, col);
break;
case TVT:
tvtpos (row, col);
break;
case GT40:
gt40pos (row, col);
break;
case BEE150:
case BEE200:
case SBEE:
case SOL:
beepos (row, col);
break;
case VC4404:
vcpos (row, col);
break;
case HAZ1510:
hazpos (row, col);
break;
case ESPRIT:
espritpos (row, col);
break;
case CG:
cgpos (row, col);
break;
case ISC8001:
iscpos (row, col);
break;
case ADM3A:
case ADM31:
case TS1:
case TVI950:
admpos (row, col);
break;
case IBM:
ibmpos (row, col);
break;
case ANP:
anppos (row, col);
break;
case NETRON:
netpos (row, col);
break;
case H19:
h19pos (row, col);
break;
case TRS80:
trspos (row, col);
break;
case VI200:
case VI50:
vipos (row, col);
break;
case VI300:
ansipos (row, col);
break;
}
#endif
}
/* setscreen --- initialize screen and associated descriptive variables */
setscreen ()
{
register int row, col;
#ifndef HARD_TERMS
t_init (); /* put out the 'ti' and 'vs' capabilities */
#endif
clrscreen (); /* clear physical screen, set cursor position */
Toprow = 0;
Botrow = Nrows - 3; /* 1 for 0-origin, 1 for status, 1 for cmd */
Cmdrow = Botrow + 1;
Topln = 1;
Sclen = -1; /* make sure we assume nothing on the screen */
for (row = 0; row < Nrows; row++) /* now clear virtual screen */
for (col = 0; col < Ncols; col++)
Screen_image[row][col] = ' ';
for (col = 0; col < Ncols; col++) /* and clear out status line */
Msgalloc[col] = NOMSG;
Insert_mode = NO;
}
/* inslines --- insert 'n' lines on the screen at 'row' */
inslines (row, n)
int row, n;
{
register int i;
int delay;
position_cursor (row, 0);
#ifdef HARD_TERMS
if (Term_type == VI300)
{
char pseq[10];
register int pp = 0;
pseq[pp++] = '\033';
pseq[pp++] = '[';
if (n >= 10)
pseq[pp++] = '0' + n / 10;
pseq[pp++] = '0' + n % 10;
pseq[pp++] = 'L';
twrite (1, pseq, pp);
delay = 0;
}
else
#endif
for (i = 0; i < n; i++)
{
#ifndef HARD_TERMS
tputs (AL, n, outc);
tflush ();
#else
switch (Term_type) {
case VI200:
twrite (1, "\033L", 2);
delay = 0;
break;
case VI50:
case H19:
twrite (1, "\033L", 2);
delay = 32;
break;
case ESPRIT:
twrite (1, "\033\032", 2);
delay = 32;
break;
case TS1:
case TVI950:
twrite (1, "\033E", 2);
delay = 0;
break;
case ADDS100:
twrite (1, "\033M", 2);
delay = 96;
break;
default:
error (YES, "in inslines: shouldn't happen");
}
if (delay != 0)
senddelay (delay);
#endif
}
for (i = Nrows - 1; i - n >= Currow; i--)
move_ (Screen_image[i - n], Screen_image[i], Ncols);
for (; i >= Currow; i--)
move_ (Blanks, Screen_image[i], Ncols);
}
/* dellines --- delete 'n' lines beginning at 'row' */
dellines (row, n)
int row, n;
{
register int i;
int delay;
position_cursor (row, 0);
#ifdef HARD_TERMS
if (Term_type == VI300)
{
char pseq[10];
register int pp = 0;
pseq[pp++] = '\033';
pseq[pp++] = '[';
if (n >= 10)
pseq[pp++] = '0' + n / 10;
pseq[pp++] = '0' + n % 10;
pseq[pp++] = 'M';
twrite (1, pseq, pp);
delay = 0;
}
else
#endif
for (i = 0; i < n; i++)
{
#ifndef HARD_TERMS
tputs (DL, n, outc);
tflush ();
#else
switch (Term_type) {
case VI200:
twrite (1, "\033M", 2);
delay = 0;
break;
case VI50:
twrite (1, "\033M", 2);
delay = 32;
break;
case H19:
twrite (1, "\033M", 2);
delay = 32;
break;
case TS1:
case TVI950:
twrite (1, "\033R", 2);
delay = 0;
break;
case ESPRIT:
twrite (1, "\033\023", 2);
delay = 32;
break;
case ADDS100:
twrite (1, "\033l", 2);
delay = 96;
break;
default:
error (YES, "in dellines: shouldn't happen");
}
if (delay != 0)
senddelay (delay);
#endif
}
for (i = Currow; i + n < Nrows; i++)
move_ (Screen_image[i + n], Screen_image[i], Ncols);
for (; i < Nrows; i++)
move_ (Blanks, Screen_image[i], Ncols);
}
/* hwinsdel --- return 1 if the terminal has hardware insert/delete */
int hwinsdel ()
{
if (No_hardware == YES)
return (NO);
#ifndef HARD_TERMS
return (AL != NULL && DL != NULL);
#else
switch (Term_type) {
case VI300:
case VI200:
case VI50:
case ESPRIT:
case H19:
case TS1:
case TVI950:
case ADDS100:
return 1;
}
return 0;
#endif
}
/* clear_to_eol --- clear screen to end-of-line */
clear_to_eol (row, col)
int row, col;
{
register int c, flag;
register int hardware = NO;
#ifdef HARD_TERMS
switch (Term_type) {
case BEE200:
case BEE150:
case FOX:
case SBEE:
case ADDS100:
case HP21:
case IBM:
case ANP:
case NETRON:
case H19:
case TS1:
case TRS80:
case ADM31:
case VI200:
case VI300:
case VI50:
case VC4404:
case ESPRIT:
case TVI950:
hardware = YES;
break;
default:
hardware = (Term_type == ADDS980 && row < Nrows - 1)
|| (Term_type == TVT && row > 0);
}
#else
hardware = (CE != NULL);
#endif
flag = NO;
for (c = col; c < Ncols; c++)
if (Screen_image[row][c] != ' ')
{
Screen_image[row][c] = ' ';
if (hardware)
flag = YES;
else
{
position_cursor (row, c);
send (' ');
}
}
if (flag == YES)
{
position_cursor (row, col);
#ifndef HARD_TERMS
tputs (CE, 1, outc);
#else
switch (Term_type) {
case BEE200:
case BEE150:
case SBEE:
case ADDS100:
case HP21:
case H19:
case VC4404:
case TS1:
case TVI950:
case VI50:
twrite (1, "\033K", 2);
break;
case FOX:
case IBM:
twrite (1, "\033I", 2);
break;
case ADDS980:
twrite (1, "\n", 1);
Currow++;
Curcol = 0;
break;
case ANP:
twrite (1, "\033L", 2);
break;
case NETRON:
twrite (1, "\005", 1);
break;
case TRS80:
twrite (1, "\036", 1);
break;
case ADM31:
twrite (1, "\033T", 2);
break;
case VI200:
twrite (1, "\033x", 2);
break;
case VI300:
twrite (1, "\033[K", 3);
break;
case ESPRIT:
twrite (1, "\033\017", 2);
break;
case TVT:
twrite (1, "\013\012", 2);
break;
} /* end switch */
#endif
} /* end if (flag == YES) */
}
/* set_term -- initialize terminal parameters and actual capabilities */
set_term (type)
char *type;
{
if (type == NULL)
error (NO, "se: terminal type not available");
if (type[0] == EOS)
error (NO, "in set_term: can't happen.");
Ncols = Nrows = -1;
#ifdef HARD_TERMS
if ((Term_type = decode_mnemonic (type)) == ERR)
error (NO, "se: could not find terminal in internal database");
switch (Term_type) {
case ADDS980:
case FOX:
case HAZ1510:
case ADDS100:
case BEE150:
case ADM3A:
case IBM:
case HP21:
case H19:
case ADM31:
case VI200:
case VC4404:
case ESPRIT:
case TS1:
case TVI950:
case VI50:
case VI300:
Nrows = 24;
Ncols = 80;
break;
case ANP:
Nrows = 24;
Ncols = 96;
break;
case SOL:
case NETRON:
case TRS80:
Nrows = 16;
Ncols = 64;
break;
case TVT:
Nrows = 16;
Ncols = 63;
break;
case GT40:
Nrows = 32;
Ncols = 73;
break;
case CG:
Nrows = 51;
Ncols = 85;
break;
case ISC8001:
Nrows = 48;
Ncols = 80;
break;
case BEE200:
case SBEE:
Nrows = 25;
Ncols = 80;
break;
}
#else
if (setcaps (type) == ERR)
error (NO, "se: could not find terminal in system database");
PC = pcstr ? pcstr[0] : EOS;
if (*tgoto (CM, 0, 0) == 'O') /* OOPS returned.. */
error (NO, "se: terminal does not have cursor motion.");
/*
* first, get it from the library. then check the
* windowing system, if there is one.
*/
winsize ();
#endif
if (Nrows == -1)
error (NO, "se: could not determine number of rows");
if (Ncols == -1)
error (NO, "se: could not determine number of columns");
return OK;
}
SHAR_EOF
fi # end of overwriting check
if test ! -d 'libchangetty'
then
echo shar: creating directory "'libchangetty'"
mkdir 'libchangetty'
fi
echo shar: entering directory "'libchangetty'"
cd 'libchangetty'
echo shar: extracting "'changetty.c'" '(5555 characters)'
if test -f 'changetty.c'
then
echo shar: will not over-write existing file "'changetty.c'"
else
cat << \SHAR_EOF > 'changetty.c'
#ifndef lint
static char RCSid[] = "$Header: changetty.c,v 1.2 86/07/11 15:23:06 osadr Exp $";
#endif
/*
* $Log: changetty.c,v $
* Revision 1.2 86/07/11 15:23:06 osadr
* Removed Georgia Tech specific code.
*
* Revision 1.1 86/05/06 13:31:06 osadr
* Initial revision
*
*
*/
/*
** changetty.c
**
** Localize in one place all the data and functions
** needed to change to and from cbreak mode for
** the se screen editor.
**
** Only functions available to rest of se are:
** ttyedit(), ttynormal(), and getspeed().
**
** If USG is defined, we use the System V TTY driver.
** Otherwise (the default) we use the Berkeley terminal driver.
**
** If we are using System V, then the Release 2 version does not
** need ospeed. If not release 2, we assume Release 1 that someone
** have moved the BSD termlib to.
*/
#include "../ascii.h"
#include "../constdefs.h"
#ifdef USG
#include <termio.h>
#else
#include <sgtty.h>
#endif
#if defined (BSD) || ! defined (S5R2)
extern short ospeed; /* from the termlib library */
static int set_ospeed = NO;
#endif
#ifdef USG
/* all the info needed for the System V terminal driver */
typedef struct termio TTYINFO; /* S5 control flags */
#else
/* all the info needed for the Berkeley terminal driver */
typedef struct junk { /* terminal information */
struct sgttyb sgttyb; /* V7 control flags */
struct tchars tchars; /* V7 control characters */
short local; /* local mode settings */
struct ltchars ltchars; /* local control characters */
} TTYINFO;
#endif
static TTYINFO OldTtyInfo; /* initial state of terminal */
static TTYINFO NewTtyInfo; /* modified state for editing */
static int first = YES; /* first time anything called */
static init()
{
if (gttyinfo(1, &OldTtyInfo) == -1) /* get current state */
error ("couldn't get TTY info from system. get help!\n");
NewTtyInfo = OldTtyInfo; /* copy it */
mttyinfo(&NewTtyInfo); /* change, but don't reset terminal */
/* really should check the return value here ... */
}
ttyedit() /* set the terminal to correct modes for editing */
{
if (first == YES)
{
first = NO;
init();
}
sttyinfo(1, &NewTtyInfo); /* make the change */
/* really should check the return value here too ... */
}
ttynormal() /* set the terminal to correct modes for normal use */
{
if (first)
{
first = NO;
init();
}
sttyinfo(1, &OldTtyInfo); /* make the change */
}
/* getspeed --- find out the terminal speed in characters/second */
/* this routine only used if terminal types are hardwired */
/* into se, however, since it will be in an archive, the */
/* loader won't grab it if it isn't needed. */
int getspeed(fd)
int fd;
{
register int i;
TTYINFO ttybuf;
static struct brstruct {
int unixrate;
int cps;
int baudrate;
} stab[] = {
B0, 0, 0,
B50, 5, 50,
B75, 8, 75,
B110, 10, 110,
B134, 14, 134,
B150, 15, 150,
B200, 20, 200,
B300, 30, 300,
B600, 60, 600,
B1200, 120, 1200,
B1800, 180, 1800,
B2400, 240, 2400,
B4800, 480, 4800,
B9600, 960, 9600
};
if (first) /* might as well set it here, too */
{
first = NO;
init();
}
if (gttyinfo(fd, &ttybuf) == -1)
return 960;
for (i = 0; i < sizeof(stab) / sizeof(struct brstruct); i++)
#ifdef USG
if (stab[i].unixrate == (ttybuf.c_cflag & 017))
#else
if (stab[i].unixrate == (ttybuf.sgttyb.sg_ospeed))
#endif
return stab[i].cps;
return 960;
}
/* gttyinfo --- make all necessary calls to obtain terminal status */
static int gttyinfo(fd, buf)
int fd; /* file descriptor of terminal */
TTYINFO *buf; /* terminal info buffer to be filled in */
{
#ifdef USG
if (ioctl(fd, TCGETA, buf) < 0)
#else
if (gtty(fd, &(buf->sgttyb)) < 0
|| ioctl(fd, TIOCGETC, &(buf->tchars)) < 0
|| ioctl(fd, TIOCLGET, &(buf->local)) < 0
|| ioctl(fd, TIOCGLTC, &(buf->ltchars)) < 0)
#endif
{
return -1;
}
#if defined (BSD) || ! defined (S5R2)
if (set_ospeed == NO)
{
set_ospeed = YES;
#ifdef BSD
ospeed = (buf->sgttyb).sg_ospeed;
#else
ospeed = buf->c_cflag & 017; /* tty speed, see termio(7) */
#endif
}
#endif
return 0;
}
/* mttyinfo --- modify a TTYINFO structure for interactive operation */
static int mttyinfo(buf)
TTYINFO *buf; /* buffer containing TTYINFO to be modified */
{
#ifdef USG
buf->c_cc[0] = DLE; /* interrupt */
buf->c_cc[1] = -1; /* ignore quit */
buf->c_cc[4] = 1; /* min # chars to read */
buf->c_cc[5] = 1; /* min time to wait */
buf->c_iflag &= ~(INLCR|IGNCR|ICRNL); /* allow CR to come thru */
buf->c_lflag |= ISIG|NOFLSH; /* keep these bits */
buf->c_lflag &= ~(ICANON|XCASE|ECHO|ECHOE|ECHOK|ECHONL);
#else
static struct tchars newtchars = {DLE, -1, DC1, DC3, EOT, -1};
static struct ltchars newltchars = {-1, -1, -1, -1, -1, -1};
buf->sgttyb.sg_flags |= (CBREAK); /* keep these bits */
buf->sgttyb.sg_flags &= ~(ECHO|CRMOD|LCASE|RAW|ALLDELAY);
buf->tchars = newtchars;
/* buf->local |= (LLITOUT); /* Dan Forsyth says to comment out */
buf->local &= ~(LCRTBS|LCRTERA|LPRTERA|LTOSTOP|LFLUSHO|LCRTKIL|
#ifndef BSD4_2
LINTRUP|
#endif
LCTLECH|LPENDIN);
buf->ltchars = newltchars;
#endif
return 0;
}
/* sttyinfo --- make all necessary calls to set terminal status */
static int sttyinfo(fd, buf)
int fd; /* file descriptor of terminal */
TTYINFO *buf; /* terminal info buffer */
{
#ifdef USG
if (ioctl(fd, TCSETAW, buf) < 0)
#else
if (ioctl(fd, TIOCSETN, &(buf->sgttyb)) < 0
|| ioctl(fd, TIOCSETC, &(buf->tchars)) < 0
|| ioctl(fd, TIOCLSET, &(buf->local)) < 0
|| ioctl(fd, TIOCSLTC, &(buf->ltchars)) < 0)
#endif
return -1;
return 0;
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'makefile'" '(734 characters)'
if test -f 'makefile'
then
echo shar: will not over-write existing file "'makefile'"
else
cat << \SHAR_EOF > 'makefile'
#
# $Header: makefile,v 1.2 86/07/11 15:23:24 osadr Exp $
#
# $Log: makefile,v $
# Revision 1.2 86/07/11 15:23:24 osadr
# Changed to ensure the proper 'ar' program is used.
#
# Revision 1.1 86/05/06 13:31:30 osadr
# Initial revision
#
#
#
# makefile for libchangetty.a -- terminal resetting functions
TARGET= libchangetty.a
SRCS= changetty.c
OBJS= changetty.o
PRINTS= $(SRCS) makefile
CFLAGS= -O `cat ../flags`
$(TARGET): $(OBJS) ../flags
/bin/ar ruv $(TARGET) $(OBJS)
if test -r /usr/bin/ranlib; then /usr/bin/ranlib $(TARGET); fi
clean:
rm -fr $(OBJS)
clobber: clean
rm -fr $(TARGET) print2
print:
prt $(PRINTS) | lpr -b 'tty lib'
touch print2
print2: $(PRINTS)
prt $? | lpr -b 'new tty lib'
touch print2
SHAR_EOF
fi # end of overwriting check
echo shar: done with directory "'libchangetty'"
cd ..
if test ! -d 'pat'
then
echo shar: creating directory "'pat'"
mkdir 'pat'
fi
echo shar: entering directory "'pat'"
cd 'pat'
echo shar: extracting "'pat.c'" '(11312 characters)'
if test -f 'pat.c'
then
echo shar: will not over-write existing file "'pat.c'"
else
cat << \SHAR_EOF > 'pat.c'
#ifndef lint
static char RCSid[] = "$Header: pat.c,v 1.2 86/07/11 15:24:44 osadr Exp $";
#endif
/*
* $Log: pat.c,v $
* Revision 1.2 86/07/11 15:24:44 osadr
* Removed Georgia Tech-ism of changeable pattern characters.
*
* Revision 1.1 86/05/06 13:32:49 osadr
* Initial revision
*
*
*/
/*
** pat.c
**
** pattern matching subroutines for the se screen editor.
**
** routines declared static are not necessary for the rest
** of the editor, therefore make them static in the name
** of modularity.
*/
#include <stdio.h>
#include <ctype.h>
#include "../constdefs.h"
/* Definitions used only for pattern matching */
#define AND '&'
#define CCL '['
#define CCLEND ']'
#define CHAR 'a'
#define CLOSIZE 1
#define CLOSURE '*'
#define DASH '-'
#define DITTO 0200
#define EOL '$'
#define NCCL 'n'
#define NEWLINE '\n'
#define TAB '\t'
#define ANY '.'
#define BOL '^'
#define NOTINCCL '^'
#define START_TAG '('
#define STOP_TAG ')'
#define ESCAPE '\\'
/* Array dimensions and other limit values */
#define MAXLINE 128
#define MAXPAT 128
/* Pattern matching subroutines: */
/* match () --- find match anywhere on line */
match (lin, pat)
register char lin[];
register char pat[];
{
int junk[9];
register char *pc;
for (pc = lin; *pc != EOS; pc++)
if (amatch (lin, pc - lin, pat, junk, junk) >= 0)
return (YES);
return (NO);
}
/* amatch() --- (recursive) look for match starting at lin[from] */
amatch(lin, from, pat, tagbeg, tagend)
int from, tagbeg[], tagend[];
char lin[], pat[];
{
char *ch, *lastc;
register char *ppat;
int k;
lastc = lin + from; /* next unexamined input character */
for (ppat = pat; *ppat != EOS; ppat += patsiz (ppat))
if (*ppat == CLOSURE) /* a closure entry */
{
ppat++;
for (ch = lastc; *ch != EOS; )
/* match as many as possible */
if (omatch (lin, &ch, ppat) == NO)
break;
/*
* ch now points to character that made us fail
* try to match rest of pattern against rest of input
* shrink the closure by 1 after each failure
*/
for (ppat += patsiz (ppat); ch >= lastc; ch--)
/* successful match of rest of pattern */
if ((k = amatch (lin, ch - lin, ppat, tagbeg,
tagend)) >= 0)
break;
lastc = lin + k; /* if k < 0, failure */
/* if k >= 0, success */
break;
}
else if (*ppat == START_TAG)
tagbeg[*(ppat + 1)] = lastc - lin;
else if (*ppat == STOP_TAG)
tagend[*(ppat + 1)] = lastc - lin;
/* non-closure */
else if (omatch (lin, &lastc, ppat) == NO)
return (-1);
/* else
omatch succeeded */
return (lastc - lin);
}
/* omatch () --- try to match a single pattern at ppat */
static omatch (lin, adplin, ppat)
char lin[], **adplin, *ppat;
{
register char *plin;
register int bump, retval;
plin = *adplin;
retval = NO;
if (*plin == EOS)
return (retval);
bump = -1;
switch (*ppat) {
case CHAR:
if (*plin == *(ppat + 1))
bump = 1;
break;
case BOL:
if (plin == lin)
bump = 0;
break;
case ANY:
if (*plin != NEWLINE)
bump = 1;
break;
case EOL:
if (*plin == NEWLINE)
bump = 0;
break;
case CCL:
if (locate (*plin, ppat + 1) == YES)
bump = 1;
break;
case NCCL:
if (*plin != NEWLINE && locate (*plin, ppat + 1) == NO)
bump = 1;
break;
default:
error ("in omatch: can't happen.");
}
if (bump >= 0)
{
*adplin += bump;
retval = YES;
}
return (retval);
}
/* locate () --- look for c in char class at ppat */
static locate (c, ppat)
register char c, *ppat;
{
register char *pclas;
/* size of class is at ppat, characters follow */
for (pclas = ppat + *ppat; pclas > ppat; pclas--)
if (c == *pclas)
return (YES);
return (NO);
}
/* patsiz () --- returns size of pattern entry at ppat */
static patsiz (ppat)
register char *ppat;
{
switch (*ppat) {
case CHAR:
case START_TAG:
case STOP_TAG:
return (2);
case BOL:
case EOL:
case ANY:
return (1);
case CCL:
case NCCL:
return (*(ppat + 1) + 2);
case CLOSURE:
return (CLOSIZE);
default:
error ("in patsiz: can't happen.");
}
}
/* makpat () --- make pattern from arg[from], terminate at delim */
makpat (arg, from, delim, pat)
char arg[], delim, pat[];
int from;
{
char ch, esc ();
int argsub, junk, lastsub, ls, patsub, tag_nest, tag_num, tag_stack[9];
lastsub = patsub = 0;
tag_num = -1;
tag_nest = -1;
for (argsub = from; arg[argsub] != delim && arg[argsub] != EOS;
argsub++)
{
ls = patsub;
if (arg[argsub] == ANY)
junk = addset (ANY, pat, &patsub, MAXPAT);
else if (arg[argsub] == BOL && argsub == from)
junk = addset (BOL, pat, &patsub, MAXPAT);
else if (arg[argsub] == EOL && arg[argsub + 1] == delim)
junk = addset (EOL, pat, &patsub, MAXPAT);
else if (arg[argsub] == CCL)
{
if (getccl (arg, &argsub, pat, &patsub) == ERR)
return (ERR);
}
else if (arg[argsub] == CLOSURE && argsub > from)
{
ls = lastsub;
if (pat[ls] == BOL || pat[ls] == EOL ||
pat[ls] == CLOSURE || pat[ls] == START_TAG ||
pat[ls] == STOP_TAG)
break;
stclos (pat, &patsub, &lastsub);
}
else if (start_tag(arg, &argsub))
{
/* too many tagged sub-patterns */
if (tag_num >= 8)
break;
tag_num++;
tag_nest++;
tag_stack[tag_nest] = tag_num;
junk = addset (START_TAG, pat, &patsub, MAXPAT);
junk = addset (tag_num, pat, &patsub, MAXPAT);
}
else if (stop_tag(arg, &argsub) && tag_nest > -1)
{
junk = addset (STOP_TAG, pat, &patsub, MAXPAT);
junk = addset (tag_stack[tag_nest], pat, &patsub, MAXPAT);
tag_nest--;
}
else
{
junk = addset (CHAR, pat, &patsub, MAXPAT);
/* don't allow match of newline other than via $ */
if ((ch = esc(arg, &argsub)) == NEWLINE)
return (ERR);
junk = addset (ch, pat, &patsub, MAXPAT);
}
lastsub = ls;
}
if (arg[argsub] != delim) /* terminated early */
return (ERR);
else if (addset (EOS, pat, &patsub, MAXPAT) == NO) /* no room */
return (ERR);
else if (tag_nest != -1)
return (ERR);
else
return (argsub);
}
/* getccl () --- expand char class at arg[*pasub] into pat[*pindex] */
static getccl (arg, pasub, pat, pindex)
char arg[], pat[];
int *pasub, *pindex;
{
int junk, start;
(*pasub)++; /* skip over [ */
if (arg[*pasub] == NOTINCCL)
{
junk = addset (NCCL, pat, pindex, MAXPAT);
(*pasub)++;
}
else
junk = addset (CCL, pat, pindex, MAXPAT);
start = *pindex;
junk = addset (0, pat, pindex, MAXPAT); /* leave room for count */
filset (CCLEND, arg, pasub, pat, pindex, MAXPAT);
pat[start] = *pindex - start - 1;
if (arg[*pasub] == CCLEND)
return (OK);
else
return (ERR);
}
/* stclos () --- insert closure entry at pat[*ppatsub] */
static stclos (pat, ppatsub, plastsub)
char pat[];
int *ppatsub, *plastsub;
{
int i, j, junk;
for (i = *ppatsub - 1; i >= *plastsub; i--) /* make a hole */
{
j = i + CLOSIZE;
junk = addset (pat[i], pat, &j, MAXPAT);
}
*ppatsub += CLOSIZE;
/* put closure in it */
junk = addset (CLOSURE, pat, plastsub, MAXPAT);
}
/* maksub () --- make substitution string in sub */
maksub (arg, from, delim, sub)
char arg[], delim, sub[];
int from;
{
char esc ();
int argsub, index, junk;
index = 0;
for (argsub = from; arg[argsub] != delim && arg[argsub] != EOS;
argsub++)
if (arg[argsub] == AND)
{
junk = addset (DITTO, sub, &index, MAXPAT);
junk = addset (0, sub, &index, MAXPAT);
}
else if (arg[argsub] == ESCAPE && isdigit (arg[argsub + 1]))
{
argsub++;
junk = addset (DITTO, sub, &index, MAXPAT);
junk = addset (arg[argsub] - '0', sub, &index, MAXPAT);
}
else
junk = addset (esc (arg, &argsub), sub, &index, MAXPAT);
if (arg[argsub] != delim) /* missing delimeter */
return (ERR);
else if (addset (EOS, sub, &index, MAXPAT) == NO) /* no room */
return (ERR);
else
return (argsub);
}
/* catsub () --- add replacement text to end of new */
catsub (lin, from, to, sub, new, k, maxnew)
register char lin[], new[], sub[];
int from[], *k, maxnew, to[];
{
int junk, ri;
register int i, j;
for (i = 0; sub[i] != EOS; i++)
if ((sub[i] & 0xff) == DITTO)
{
ri = sub[++i];
for (j = from[ri]; j < to[ri]; j++)
junk = addset (lin[j], new, k, maxnew);
}
else
junk = addset (sub[i], new, k, maxnew);
}
/* filset () --- expand set at array[*pasub] into set[*pindex], stop at delim */
filset (delim, array, pasub, set, pindex, maxset)
char array[], delim, set[];
int maxset, *pasub, *pindex;
{
char esc ();
int junk;
static char digits[] = "0123456789";
static char lowalf[] = "abcdefghijklmnopqrstuvwxyz";
static char upalf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for ( ; array[*pasub] != delim && array[*pasub] != EOS; (*pasub)++)
if (array[*pasub] == ESCAPE)
junk = addset (esc (array, pasub), set, pindex, maxset);
else if (array[*pasub] != DASH)
junk = addset (array[*pasub], set, pindex, maxset);
/* literal DASH */
else if (*pindex <= 0 || array[*pasub + 1] == EOS ||
array[*pasub + 1] == delim)
junk = addset (DASH, set, pindex, maxset);
/* else if (index (digits, set[*pindex - 1]) >= 0) */
else if (isdigit(set[*pindex - 1]))
dodash (digits, array, pasub, set, pindex, maxset);
/* else if(index (lowalf, set[*pindex - 1]) >= 0) */
else if (islower(set[*pindex - 1]))
dodash (lowalf, array, pasub, set, pindex, maxset);
/* else if (index (upalf, set[*pindex - 1]) >= 0) */
else if (isupper(set[*pindex - 1]))
dodash (upalf, array, pasub, set, pindex, maxset);
else
junk = addset (DASH, set, pindex, maxset);
}
/*
** dodash () --- expand array[*pasub - 1]-array[*pasub + 1] into set[*pindex],
** from valid
*/
static dodash (valid, array, pasub, set, pindex, maxset)
char array[], set[], valid[];
int maxset, *pasub, *pindex;
{
char esc ();
int junk, k, limit;
(*pasub)++;
(*pindex)--;
limit = index (valid, esc (array, pasub));
for (k = index (valid, set[*pindex]); k <= limit; k++)
junk = addset (valid[k], set, pindex, maxset);
}
/* addset () --- put c in set[*pindex]; if it fits, increment *pindex */
addset (c, set, pindex, maxsiz)
int maxsiz, *pindex;
char c, set[];
{
if (*pindex >= maxsiz)
return (NO);
else
{
set[(*pindex)++] = c;
return (YES);
}
}
/* esc () --- map array[*pindex] into escaped character if appropriate */
char esc (array, pindex)
char array[];
int *pindex;
{
if (array[*pindex] != ESCAPE)
return (array[*pindex]);
else if (array[*pindex + 1] == EOS) /* ESCAPE not special at end */
return (ESCAPE);
else
{
if (array[++(*pindex)] == 'n')
return (NEWLINE);
else if (array[*pindex] == 't')
return (TAB);
else
return (array[*pindex]);
}
}
/* start_tag --- determine if we've seen the start of a tagged pattern */
static int start_tag(arg, argsub)
char *arg;
int *argsub;
{
if (arg[*argsub] == ESCAPE && arg[*argsub + 1] == START_TAG)
{
(*argsub)++;
return (YES);
}
else
return (NO);
}
/* stop_tag --- determine if we've seen the end of a tagged pattern */
static int stop_tag(arg, argsub)
char *arg;
int *argsub;
{
if (arg[*argsub] == ESCAPE && arg[*argsub + 1] == STOP_TAG)
{
(*argsub)++;
return (YES);
}
else
return (NO);
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'makefile'" '(673 characters)'
if test -f 'makefile'
then
echo shar: will not over-write existing file "'makefile'"
else
cat << \SHAR_EOF > 'makefile'
#
# $Header: makefile,v 1.2 86/07/11 15:25:14 osadr Exp $
#
# $Log: makefile,v $
# Revision 1.2 86/07/11 15:25:14 osadr
# Changed to ensure that the proper 'ar' program gets used.
#
# Revision 1.1 86/05/06 13:33:07 osadr
# Initial revision
#
#
#
# makefile for pattern library for 'se'
CFLAGS=-O
PR=pr
libpat.a: pat.o
/bin/ar ruv libpat.a pat.o
if test -r /usr/bin/ranlib; then /usr/bin/ranlib libpat.a; fi
pat.o: pat.c
install: libpat.a
cp libpat.a /usr/lib
print:
$(PR) pat.c makefile | lpr -b 'pat lib'
touch print2
print2: pat.c makefile
$(PR) $? | lpr -b 'new pat lib'
touch print2
clean:
rm -f pat.o
clobber: clean
rm -f libpat.a print2
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'llib-lpat'" '(1270 characters)'
if test -f 'llib-lpat'
then
echo shar: will not over-write existing file "'llib-lpat'"
else
cat << \SHAR_EOF > 'llib-lpat'
/* llib-lpat --- lint library for pattern routines */
/*LINTLIBRARY*/
match (lin, pat)
char lin[];
char pat[];
{
return 0;
}
amatch(lin, from, pat, tagbeg, tagend)
int from, tagbeg[], tagend[];
char lin[], pat[];
{
return 0;
}
static omatch (lin, adplin, ppat)
char lin[], **adplin, *ppat;
{
return 0;
}
static locate (c, ppat)
char c, *ppat;
{
return 0;
}
static patsiz (ppat)
char *ppat;
{
return 0;
}
makpat (arg, from, delim, pat)
char arg[], delim, pat[];
int from;
{
return 0;
}
static getccl (arg, pasub, pat, pindex)
char arg[], pat[];
int *pasub, *pindex;
{
return 0;
}
static stclos (pat, ppatsub, plastsub)
char pat[];
int *ppatsub, *plastsub;
{
}
maksub (arg, from, delim, sub)
char arg[], delim, sub[];
int from;
{
return 0;
}
catsub (lin, from, to, sub, new, k, maxnew)
char lin[], new[], sub[];
int from[], *k, maxnew, to[];
{
}
filset (delim, array, pasub, set, pindex, maxset)
char array[], delim, set[];
int maxset, *pasub, *pindex;
{
}
static dodash (valid, array, pasub, set, pindex, maxset)
char array[], set[], valid[];
int maxset, *pasub, *pindex;
{
}
addset (c, set, pindex, maxsiz)
int maxsiz, *pindex;
char c, set[];
{
return 0;
}
char esc (array, pindex)
char array[];
int *pindex;
{
return 0;
}
SHAR_EOF
fi # end of overwriting check
echo shar: done with directory "'pat'"
cd ..
# End of shell archive
exit 0
More information about the Mod.sources
mailing list