mirror of
https://github.com/IanDarwin/OpenLookCDROM.git
synced 2026-02-13 11:34:52 +00:00
1534 lines
34 KiB
C
1534 lines
34 KiB
C
/*
|
|
* This file is a product of Sun Microsystems, Inc. and is provided for
|
|
* unrestricted use provided that this legend is included on all tape
|
|
* media and as a part of the software program in whole or part.
|
|
* Users may copy, modify or distribute this file at will.
|
|
*
|
|
* THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
|
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
|
*
|
|
* This file is provided with no support and without any obligation on the
|
|
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
|
* modification or enhancement.
|
|
*
|
|
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
|
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE
|
|
* OR ANY PART THEREOF.
|
|
*
|
|
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
|
* or profits or other special, indirect and consequential damages, even
|
|
* if Sun has been advised of the possibility of such damages.
|
|
*
|
|
* Sun Microsystems, Inc.
|
|
* 2550 Garcia Avenue
|
|
* Mountain View, California 94043
|
|
*
|
|
* Modifications to the original Sun Microsystems, Inc. source code
|
|
* made by the Grasshopper Group are in the Public Domain.
|
|
*
|
|
* Extensions to this file by Eric Messick of the Grasshopper Group.
|
|
*
|
|
* Grasshopper Group
|
|
* 212 Clayton St
|
|
* San Francisco, CA 94117
|
|
*
|
|
*/
|
|
|
|
#ifndef lint
|
|
static char sccsid[] = "@(#)tcap_ops.c 9.6 88/01/19 Copyright 1985 Sun Micro";
|
|
static char RCSid[] =
|
|
"@(#)$Header: /it/grass/gterm/RCS/tcap_ops.c,v 2.7 1991/04/23 06:52:40 hugh Grass2 $";
|
|
#endif
|
|
|
|
/*
|
|
* Copyright (c) 1985 by Sun Microsystems, Inc.
|
|
*/
|
|
|
|
/*-
|
|
tcap_ops.c
|
|
|
|
tcap_ops.c, Mon Mar 24 11:52:31 1986
|
|
|
|
David Rosenthal,
|
|
Sun Microsystems
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#ifdef REF
|
|
#include <ref/config.h>
|
|
#endif
|
|
#include "termcap.h"
|
|
#include "tcap.h"
|
|
|
|
/*
|
|
* Termcap operations module.
|
|
*
|
|
* The external interface of this module is the array T[] and its
|
|
* number of elements Ts, plus the initialization routine:
|
|
* tc_init_ops()
|
|
*/
|
|
|
|
#include "screen.h"
|
|
extern int CharsPerLine;
|
|
extern int LinesPerScreen;
|
|
extern struct pair Dot;
|
|
extern struct tcap T[];
|
|
extern int Ts;
|
|
extern char *malloc();
|
|
#ifndef bcopy
|
|
extern void bcopy();
|
|
#endif
|
|
#ifndef bzero
|
|
extern void bzero();
|
|
#endif
|
|
extern char *strncpy();
|
|
static struct tcap *tc_lookup();
|
|
|
|
static u_short TopLineOfScrollRegion, BottomLineOfScrollRegion;
|
|
static struct pair SavedCursor;
|
|
static u_short ScrollNLKludge = 0;
|
|
struct tcap *CheckCR = 0;
|
|
struct tcap *CheckNL = 0;
|
|
struct tcap *CheckBS = 0;
|
|
struct tcap *CheckTAB = 0;
|
|
|
|
static unsigned int PermanentModes = 0, TemporaryModes = 0;
|
|
|
|
static char FrameLabel[MaxCharsPerLine] ;
|
|
static u_short FLindex=-1;
|
|
static int (*prevInput)();
|
|
|
|
struct tcap interruptedOp = { 0 };
|
|
struct line *lastInputLine;
|
|
int PageFull = 0;
|
|
static int PrevPageMode = -1;
|
|
extern int PageMode;
|
|
extern int userLinesPerScreen;
|
|
extern int userCharsPerLine;
|
|
|
|
static int al_op(), clear_body(), ce_op(), cm_in(), cs_op();
|
|
static int dc_op(), dl_op(), ic_op(), nl_op(), sf_op();
|
|
|
|
tc_init_ops()
|
|
{
|
|
struct tcap *me, *tc;
|
|
|
|
if (userLinesPerScreen > 0)
|
|
LinesPerScreen = userLinesPerScreen;
|
|
if (userCharsPerLine > 0)
|
|
CharsPerLine = userCharsPerLine;
|
|
Dot.x = 0 ;
|
|
Dot.y = LinesPerScreen - 1 ;
|
|
TopLineOfScrollRegion = 0;
|
|
BottomLineOfScrollRegion = LinesPerScreen - 1;
|
|
/*
|
|
* Beware of termcap entries that define ue and/or se identical
|
|
* to me (turn off ALL attributes). Since we just pattern
|
|
* match, it's likely we won't get me_op in normal operation,
|
|
* so force the entries here. (known for vt100)
|
|
*/
|
|
me = tc_lookup("me");
|
|
if (me) {
|
|
tc = tc_lookup("ue");
|
|
if (tc && tc->t_size == me->t_size &&
|
|
bcmp(me->t_text, tc->t_text, (int)tc->t_size) == 0)
|
|
tc->t_op = me->t_op;
|
|
tc = tc_lookup("se");
|
|
if (tc && tc->t_size == me->t_size &&
|
|
bcmp(me->t_text, tc->t_text, (int)tc->t_size) == 0)
|
|
tc->t_op = me->t_op;
|
|
}
|
|
/*
|
|
* Check for sf == \n, if so we must kludge things so that
|
|
* sf_op will call nl_op as needed (exists on bitgraph).
|
|
*/
|
|
tc = tc_lookup("sf");
|
|
if (tc && tc->t_size == 1 && tc->t_text[0] == '\n')
|
|
ScrollNLKludge = 1;
|
|
/*
|
|
* To minimize the number of times the regular text processing
|
|
* is stopped to invoke the pattern matcher we check the most
|
|
* strings CR, NL, BS, and TAB to see if they are \r, \n, \b,,
|
|
* and \t, respectively. If any are, a quick check on the character
|
|
* is made before the pattern matching machinery is invoked.
|
|
*/
|
|
tc = tc_lookup("cr");
|
|
if (tc && tc->t_size == 1 && tc->t_text[0] == '\r')
|
|
CheckCR = tc;
|
|
tc = tc_lookup("nl");
|
|
if (tc && tc->t_size == 1 && tc->t_text[0] == '\n')
|
|
CheckNL = tc;
|
|
tc = tc_lookup("bc");
|
|
if (tc && tc->t_size == 1 && tc->t_text[0] == '\b')
|
|
CheckBS = tc;
|
|
tc = tc_lookup("ta");
|
|
if (tc && tc->t_size == 1 && tc->t_text[0] == '\t')
|
|
CheckTAB = tc;
|
|
}
|
|
|
|
tc_initmodemenu()
|
|
{
|
|
|
|
/*
|
|
* Insure menu items properly reflect initial settings.
|
|
*/
|
|
SetPageMode(PageMode);
|
|
SetAutoMargins(PermanentModes & AutoMarginMode);
|
|
}
|
|
|
|
static struct tcap *
|
|
tc_lookup(key)
|
|
char *key;
|
|
{
|
|
register struct tcap *tp;
|
|
|
|
for (tp = T; *tp->t_key; tp++)
|
|
if (strcmp(tp->t_key, key) == 0)
|
|
return (tp);
|
|
return ((struct tcap *)0);
|
|
}
|
|
|
|
/*
|
|
* scrollreset is called whenever keyboard input is seen, in order to
|
|
* do deferred scrolling and remember the last line on which the user
|
|
* typed something.
|
|
*/
|
|
|
|
scrollreset(l)
|
|
int l;
|
|
{
|
|
int n = PageFull;
|
|
|
|
PageFull = 0;
|
|
lastInputLine = (l == 1) ? screen[1] : 0;
|
|
while (n-- > 0 && !PageFull)
|
|
sf_op((struct tcap *) 0);
|
|
if (lastInputLine == 0)
|
|
lastInputLine = screen[Dot.y];
|
|
}
|
|
|
|
toggleautomargins()
|
|
{
|
|
|
|
PermanentModes ^= (unsigned int) AutoMarginMode;
|
|
SetAutoMargins(PermanentModes & AutoMarginMode);
|
|
FlushPostScript();
|
|
}
|
|
|
|
togglepagemode()
|
|
{
|
|
SetPageMode(PageMode = !PageMode);
|
|
FlushPostScript();
|
|
}
|
|
|
|
resetscreensize(row, col)
|
|
int row, col;
|
|
{
|
|
struct tcap t;
|
|
int dotx, doty;
|
|
|
|
dotx = Dot.x ;
|
|
if (dotx >= col) dotx = col - 1;
|
|
|
|
doty = Dot.y - LinesPerScreen + row ;
|
|
if (doty >= row) doty = row - 1;
|
|
if (doty < 0) doty = 0 ;
|
|
|
|
if (PageMode) {
|
|
/* no scroll stop line */
|
|
lastInputLine = screen[doty - row + LinesPerScreen];
|
|
}
|
|
|
|
CharsPerLine = col ;
|
|
LinesPerScreen = row ;
|
|
|
|
t.t_x = LinesPerScreen - 1 ;
|
|
t.t_y = 0 ;
|
|
cs_op(&t); /* change scrolling region to full screen */
|
|
/* if it wasn't full screen before, then it's the
|
|
* program's responsibility to change it after
|
|
* getting the sigwinch
|
|
* note that this trashes Dot, so we save it.
|
|
*/
|
|
Dot.x = dotx ;
|
|
Dot.y = doty ;
|
|
}
|
|
|
|
#ifdef notdef
|
|
static
|
|
trace(s, t)
|
|
register char *s;
|
|
register struct tcap *t;
|
|
{
|
|
register char *q = t->t_text;
|
|
|
|
fprintf(stderr, "%s: ", s);
|
|
fprintf(stderr, "[%s,", t->t_key);
|
|
if (q == NULL)
|
|
fprintf(stderr, "(nil)");
|
|
else while (*q) {
|
|
if (*q < ' ') {
|
|
fprintf(stderr, "^%c", *q + '@');
|
|
} else {
|
|
fprintf(stderr, "%c", *q);
|
|
}
|
|
q++;
|
|
}
|
|
fprintf(stderr, ",%d,(%d,%d)]\n", t->t_index, t->t_x, t->t_y);
|
|
}
|
|
#endif
|
|
|
|
#ifndef notdef
|
|
#define trace(X, Y) (void)(X, Y)
|
|
#endif
|
|
#define ChangeScreen()
|
|
#define MoveCursor()
|
|
|
|
#ifdef notdef
|
|
static
|
|
PrintScreen()
|
|
{
|
|
register int y;
|
|
|
|
for (y = 0; y < LinesPerScreen; y++) {
|
|
register struct line *l = screen[y];
|
|
register int x;
|
|
|
|
if (l == NULL)
|
|
fprintf(stderr, "(nil)");
|
|
else for (x = 0; x < l->length; x++) {
|
|
if (x == Dot.x && y == Dot.y)
|
|
fprintf(stderr, "+");
|
|
else if (x == l->changeposition)
|
|
fprintf(stderr, "|");
|
|
else
|
|
fprintf(stderr, "%c", (l->body[x] == ' ' ? '.' : l->body[x]));
|
|
}
|
|
fprintf(stderr, "\n");
|
|
}
|
|
fprintf(stderr, "\n");
|
|
}
|
|
#endif
|
|
|
|
showc(t)
|
|
struct tcap *t;
|
|
{
|
|
register char *cp = t->t_text;
|
|
register struct line *l;
|
|
register int dotx, c;
|
|
register unsigned Modes = PermanentModes | TemporaryModes;
|
|
int n = t->t_size;
|
|
register char *bp;
|
|
register u_char *pp;
|
|
|
|
trace("==", t);
|
|
TemporaryModes = 0;
|
|
dotx = Dot.x;
|
|
while (n > 0 && !PageFull) {
|
|
l = screen[Dot.y];
|
|
if (l->changeposition > dotx)
|
|
l->changeposition = dotx;
|
|
if (l->length < dotx)
|
|
l->length = dotx;
|
|
bp = &l->body[dotx] ;
|
|
pp = &l->prop[dotx] ;
|
|
if (Modes & InsertMode && l->length > dotx) {
|
|
n-- ;
|
|
c = *cp++;
|
|
if (c < ' ' || c >= 0177)
|
|
continue;
|
|
if (l->length < CharsPerLine)
|
|
l->length++;
|
|
|
|
bcopy((char *)pp, (char *)pp+1,(int)(l->length-dotx-1));
|
|
bcopy( bp, bp+1,(int)(l->length-dotx-1));
|
|
|
|
l->end_of_changes = CharsPerLine + 1 ;
|
|
*bp = c;
|
|
*pp = (Modes & Attributes);
|
|
if (++dotx >= CharsPerLine) {
|
|
if (Modes & AutoMarginMode) {
|
|
trace("cr", t);
|
|
l->end_of_changes = CharsPerLine + 1 ;
|
|
l->flags |= LINE_WRAPPED ;
|
|
if (l->length < dotx)
|
|
l->length = dotx ;
|
|
dotx = 0;
|
|
MoveCursor();
|
|
nl_op(t);
|
|
TemporaryModes |= WrapJustHappenedMode;
|
|
}
|
|
else dotx = CharsPerLine - 1;
|
|
}
|
|
}
|
|
else {
|
|
while (n-- > 0 && !PageFull) {
|
|
c = *cp++;
|
|
if (c < ' ' || c >= 0177)
|
|
continue;
|
|
*bp++ = c;
|
|
*pp++ = (Modes & Attributes);
|
|
if (++dotx >= CharsPerLine) {
|
|
if (Modes & AutoMarginMode) {
|
|
trace("cr", t);
|
|
l->end_of_changes =
|
|
CharsPerLine + 1 ;
|
|
l->flags |= LINE_WRAPPED ;
|
|
if (l->length < dotx)
|
|
l->length = dotx ;
|
|
dotx = 0;
|
|
MoveCursor();
|
|
nl_op(t);
|
|
TemporaryModes |=
|
|
WrapJustHappenedMode;
|
|
break;
|
|
}
|
|
else dotx = CharsPerLine - 1;
|
|
}
|
|
}
|
|
}
|
|
if (l->length < dotx)
|
|
l->length = dotx ;
|
|
if (l->end_of_changes < dotx)
|
|
l->end_of_changes = dotx;
|
|
}
|
|
Dot.x = dotx;
|
|
ChangeScreen();
|
|
/*
|
|
* If we were interrupted by nl_op setting PageFull, set up
|
|
* interruptedOp with a tcap that can be used to finish this later.
|
|
*/
|
|
if (PageFull && ++n > 0) {
|
|
interruptedOp = *t;
|
|
interruptedOp.t_text += (t->t_size - n);
|
|
interruptedOp.t_size = n;
|
|
}
|
|
else interruptedOp.t_op = 0;
|
|
}
|
|
|
|
static int
|
|
AL_op(t) /* add multiple blank lines */
|
|
struct tcap *t;
|
|
{
|
|
trace("AL", t);
|
|
/* cheat for now */
|
|
while (t->t_y-- > 0)
|
|
al_op(t);
|
|
ChangeScreen();
|
|
}
|
|
|
|
static int
|
|
DC_op(t)
|
|
struct tcap *t;
|
|
{
|
|
trace("DC", t);
|
|
/* cheat for now */
|
|
while (t->t_y-- > 0)
|
|
dc_op(t);
|
|
ChangeScreen();
|
|
}
|
|
|
|
static int
|
|
DL_op(t) /* delete multiple lines */
|
|
struct tcap *t;
|
|
{
|
|
trace("DL", t);
|
|
/* cheat for now */
|
|
while (t->t_y-- > 0)
|
|
dl_op(t);
|
|
ChangeScreen();
|
|
}
|
|
|
|
static int
|
|
DO_in(t) /* move cursor down n lines */
|
|
struct tcap *t;
|
|
{
|
|
trace("DO", t);
|
|
return (cm_in(t)); /* Neat! It might even work */
|
|
}
|
|
|
|
static int
|
|
DO_op(t) /* move cursor down n lines */
|
|
register struct tcap *t;
|
|
{
|
|
trace("DO", t);
|
|
if (t->t_y >= 0 && (Dot.y + t->t_y) < LinesPerScreen)
|
|
Dot.y += t->t_y;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
IC_op(t)
|
|
struct tcap *t;
|
|
{
|
|
trace("IC", t);
|
|
/* cheat for now */
|
|
while (t->t_y-- > 0)
|
|
ic_op(t);
|
|
ChangeScreen();
|
|
}
|
|
|
|
static int
|
|
LE_in(t) /* move cursor left n characters */
|
|
struct tcap *t;
|
|
{
|
|
trace("LE", t);
|
|
return (cm_in(t)); /* Neat! It might even work */
|
|
}
|
|
|
|
static int
|
|
LE_op(t) /* move cursor left n characters */
|
|
register struct tcap *t;
|
|
{
|
|
trace("LE", t);
|
|
if ((Dot.x - t->t_y) >= 0)
|
|
Dot.x -= t->t_y;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
RI_in(t) /* move cursor right n characters */
|
|
struct tcap *t;
|
|
{
|
|
trace("RI", t);
|
|
return (cm_in(t)); /* Neat! It might even work */
|
|
}
|
|
|
|
static int
|
|
RI_op(t) /* move cursor right n characters */
|
|
register struct tcap *t;
|
|
{
|
|
trace("RI", t);
|
|
if (t->t_y >= 0 && (Dot.x + t->t_y) <= CharsPerLine)
|
|
Dot.x += t->t_y;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
UP_in(t) /* move cursor up n lines */
|
|
struct tcap *t;
|
|
{
|
|
trace("UP", t);
|
|
return (cm_in(t)); /* Neat! It might even work */
|
|
}
|
|
|
|
static int
|
|
UP_op(t) /* move cursor up n lines */
|
|
register struct tcap *t;
|
|
{
|
|
trace("UP", t);
|
|
if ((Dot.y - t->t_y) >= 0)
|
|
Dot.y -= t->t_y;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
al_op(t) /* Add new blank line */
|
|
struct tcap *t;
|
|
{
|
|
register struct line **p, **current;
|
|
register struct line *old;
|
|
|
|
trace("al", t);
|
|
current = &screen[Dot.y];
|
|
p = &screen[BottomLineOfScrollRegion];
|
|
old = *p;
|
|
for (; p > current; p--)
|
|
*p = *(p-1);
|
|
*p = old;
|
|
clear_body(old, 0);
|
|
old->length = 0;
|
|
old->changeposition = 0;
|
|
old->end_of_changes = CharsPerLine;
|
|
old->usedtobe = LinesPerScreen;
|
|
ChangeScreen();
|
|
}
|
|
|
|
static int
|
|
am_in(t) /* Has auto-margins */
|
|
struct tcap *t;
|
|
{
|
|
trace("am", t);
|
|
if (t->t_x) PermanentModes |= AutoMarginMode;
|
|
return (0);
|
|
}
|
|
|
|
static int
|
|
bc_op(t) /* back-character */
|
|
struct tcap *t;
|
|
{
|
|
trace("bc", t);
|
|
if (Dot.x > 0)
|
|
Dot.x--;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
bl_op(t) /* Bell character */
|
|
struct tcap *t;
|
|
{
|
|
trace("bl", t);
|
|
RingBell();
|
|
}
|
|
|
|
/*
|
|
* Clearing the whole line body for the clear ops may be excessive
|
|
* but nothing short of it seems to work for programs which do a lot
|
|
* of cursor manipulation, such as rogue or hack.
|
|
*/
|
|
static int
|
|
clear_body(l, x)
|
|
struct line *l;
|
|
int x;
|
|
{
|
|
register int len = l->buffer_length - x;
|
|
register char *cp;
|
|
|
|
bzero((char *)&l->prop[x], len);
|
|
l->flags = 0 ;
|
|
for (cp = &l->body[x]; len-- > 0;)
|
|
*cp++ = ' ';
|
|
}
|
|
|
|
static int
|
|
cd_op(t) /* Clear to end of display */
|
|
struct tcap *t;
|
|
{
|
|
register struct line **p, **last;
|
|
register struct line *l;
|
|
|
|
trace("cd", t);
|
|
ce_op(t);
|
|
last = &screen[LinesPerScreen];
|
|
for (p = &screen[Dot.y+1]; p < last; p++) {
|
|
(l = *p)->length = 0;
|
|
l->changeposition = 0;
|
|
l->end_of_changes = CharsPerLine ;
|
|
clear_body(l, 0);
|
|
}
|
|
ChangeScreen();
|
|
}
|
|
|
|
static int
|
|
ce_op(t) /* Clear to end of line */
|
|
struct tcap *t;
|
|
{
|
|
register struct line *l = screen[Dot.y];
|
|
|
|
trace("ce", t);
|
|
l->length = Dot.x;
|
|
if (l->changeposition > Dot.x)
|
|
l->changeposition = Dot.x;
|
|
l->end_of_changes = CharsPerLine ;
|
|
clear_body(l, (int)l->length);
|
|
ChangeScreen();
|
|
}
|
|
|
|
static int
|
|
cl_op(t) /* Clear screen */
|
|
struct tcap *t;
|
|
{
|
|
register struct line **p, **last;
|
|
register struct line *l;
|
|
extern int RefreshSuppressed;
|
|
|
|
trace("cl", t);
|
|
Dot.x = Dot.y = 0;
|
|
last = &screen[LinesPerScreen];
|
|
for (p = &screen[0]; p < last; p++) {
|
|
(l = *p)->length = 0;
|
|
if (RefreshSuppressed) {
|
|
l->changeposition = 0;
|
|
l->end_of_changes = CharsPerLine ;
|
|
} else {
|
|
l->changeposition = MaxCharsPerLine + 1;
|
|
l->end_of_changes = 0;
|
|
}
|
|
clear_body(l, 0);
|
|
}
|
|
if (!RefreshSuppressed) {
|
|
ClearScreen();
|
|
FlushPostScript();
|
|
}
|
|
ChangeScreen();
|
|
if (PageMode)
|
|
lastInputLine = screen[Dot.y]; /* no scroll stop line */
|
|
}
|
|
|
|
#ifdef HAVE_TERMCAP
|
|
static int
|
|
cm_in(t) /* Cursor motion */
|
|
register struct tcap *t;
|
|
{
|
|
register u_char c;
|
|
char buf[128];
|
|
register char *cp = t->t_text, *bp = buf;
|
|
|
|
trace("cm", t);
|
|
|
|
if (cp == NULL)
|
|
return(0);
|
|
/* Pre-process out parts of the % escapes */
|
|
while ((c = *cp++) != '\0') {
|
|
if (c == '%') {
|
|
register u_char c2 = *cp++;
|
|
|
|
switch (c2) {
|
|
case '+': /* Subtract next then %. */
|
|
switch (t->t_2nd + t->t_pc_r) {
|
|
case 0:
|
|
case 2:
|
|
t->t_yi = *cp++;
|
|
break;
|
|
case 1:
|
|
t->t_xi = *cp++;
|
|
break;
|
|
}
|
|
c2 = '.';
|
|
goto percent_dot;
|
|
case '>':
|
|
switch (t->t_2nd + t->t_pc_r) {
|
|
case 1:
|
|
t->t_xilim = *cp++;
|
|
t->t_xi = *cp++;
|
|
t->t_xilim += t->t_xi + 1;
|
|
break;
|
|
case 0:
|
|
case 2:
|
|
t->t_yilim = *cp++;
|
|
t->t_yi = *cp++;
|
|
t->t_yilim += t->t_yi + 1;
|
|
break;
|
|
}
|
|
t->t_2nd = !t->t_2nd;
|
|
break;
|
|
case 'r':
|
|
t->t_pc_r = 1;
|
|
break;
|
|
case 'i':
|
|
t->t_xi++;
|
|
t->t_yi++;
|
|
break;
|
|
case 'n':
|
|
t->t_pc_n = 1;
|
|
break;
|
|
case 'B':
|
|
t->t_pc_B = 1;
|
|
break;
|
|
case 'D':
|
|
t->t_pc_D = 1;
|
|
break;
|
|
/* The following ones will be interpreted on the fly */
|
|
case 'd': /* series of decimal digits */
|
|
case '2': /* two decimal digits */
|
|
case '3': /* three decimal digits */
|
|
case '.': /* binary character */
|
|
percent_dot:
|
|
case '%':
|
|
*bp++ = c;
|
|
*bp++ = c2;
|
|
t->t_2nd = !t->t_2nd;
|
|
break;
|
|
default: /* Bad % escape */
|
|
return (1);
|
|
}
|
|
}
|
|
else {
|
|
*bp++ = c;
|
|
}
|
|
}
|
|
*bp++ = '\0';
|
|
if (bp-buf > 1) {
|
|
if ((t->t_text = malloc((unsigned)(bp-buf+1))) == NULL)
|
|
return (2);
|
|
strncpy(t->t_text, buf, bp-buf);
|
|
t->t_size = bp-buf - 1;
|
|
} else {
|
|
t->t_text = NULL;
|
|
}
|
|
t->t_2nd = 0;
|
|
return (0);
|
|
}
|
|
|
|
#else /* !HAVE_TERMCAP */
|
|
|
|
static int
|
|
cm_in(t) /* Cursor motion */
|
|
register struct tcap *t;
|
|
{
|
|
register u_char c;
|
|
char buf[128];
|
|
register char *cp = t->t_text, *bp = buf;
|
|
|
|
trace("cm", t);
|
|
|
|
if (cp == NULL)
|
|
return(0);
|
|
/* Pre-process out parts of the % escapes */
|
|
while ((c = *cp++) != '\0') {
|
|
static int seen1 = 0;
|
|
|
|
if (c == '%') {
|
|
register u_char c2 = *cp++;
|
|
|
|
switch (c2) {
|
|
case 'p':
|
|
switch (*cp++) {
|
|
case '1':
|
|
seen1++;
|
|
t->t_2nd = 0;
|
|
break;
|
|
case '2':
|
|
if (!seen1)
|
|
t->t_pc_r = 1;
|
|
t->t_2nd = 1;
|
|
break;
|
|
/*
|
|
* This capability is not available in termcap so we will
|
|
* assume that it is not present in terminfo either. This
|
|
* means that terminal that send more than two pieces of
|
|
* variable data with the "cm" directive will not work.
|
|
* Currently for "cm" only two variables are defined.
|
|
*/
|
|
case '3':
|
|
case '4':
|
|
case '5':
|
|
case '6':
|
|
case '7':
|
|
case '8':
|
|
case '9':
|
|
return(1);
|
|
}
|
|
break;
|
|
|
|
case '\'': /* store constant for future operator */
|
|
switch (t->t_2nd + t->t_pc_r) {
|
|
case 0:
|
|
case 2:
|
|
t->t_yi = *cp++;
|
|
break;
|
|
case 1:
|
|
t->t_xi = *cp++;
|
|
break;
|
|
}
|
|
if (*cp == '\'')
|
|
cp++; /* blow past the trailing '\'' */
|
|
else
|
|
return(1);
|
|
break;
|
|
case '{': /* store decimal constant for future operator */
|
|
switch (t->t_2nd + t->t_pc_r) {
|
|
case 0:
|
|
case 2:
|
|
t->t_yi = ((*cp++) * 10) + (*cp++);
|
|
break;
|
|
case 1:
|
|
t->t_xi = ((*cp++) * 10) + (*cp++);
|
|
break;
|
|
}
|
|
if (*cp == '}')
|
|
cp++; /* blow past trailing '}' */
|
|
else
|
|
return(1);
|
|
break;
|
|
/* the following will not work do to the simplifications here */
|
|
case '?': /* if */
|
|
case 't': /* then */
|
|
case 'e': /* else */
|
|
return(1); /* lets not delude ourselves, the data
|
|
* structures were set up to deal with termcap
|
|
* not the complexities of terminfo.
|
|
*/
|
|
case 'i':
|
|
t->t_xi++;
|
|
t->t_yi++;
|
|
break;
|
|
case '+':
|
|
if (*cp++ != '%')
|
|
return(1);
|
|
if (*cp++ != 'c')
|
|
return(1);
|
|
*bp++ = '%'; /* make it look like termcap */
|
|
*bp++ = '.';
|
|
break;
|
|
/* use the simpified model of termcap so some of this
|
|
* stuff is not valid
|
|
*/
|
|
case '\b': /* flags in format string */
|
|
case ':': /* needed for '-' and '+' flags */
|
|
case '#': /* flags in format string */
|
|
case '.': /* if only fract part of precision */
|
|
return(1);
|
|
/* just leave a 'd' */
|
|
case '0': /* numeric part of precision */
|
|
case '1': /* numeric part of precision */
|
|
case '4': /* numeric part of precision */
|
|
case '5': /* numeric part of precision */
|
|
case '6': /* numeric part of precision */
|
|
case '7': /* numeric part of precision */
|
|
case '8': /* numeric part of precision */
|
|
case '9': /* numeric part of precision */
|
|
/* skip past the end of this definition, leave %d in its place*/
|
|
while (*cp != 'd' && *cp != 'o' && *cp != 'x'
|
|
&& *cp != 'X' && *cp != 's')
|
|
cp++;
|
|
/* don't support anything but 'd' */
|
|
if (*cp != 'd')
|
|
return(1);
|
|
*bp++ = c; /* '%' */
|
|
*bp++ = *cp++; /* 'd' */
|
|
/* The following ones will be interpreted on the fly. */
|
|
case '2': /* numeric part of precision */
|
|
case '3': /* numeric part of precision */
|
|
/* remove %[23]->[doxXs], put %[23] in bp */
|
|
*bp++ = c;
|
|
*bp++ = c2;
|
|
/* skip any factional part of the precision */
|
|
while (*cp != 'd' && *cp != 'o' && *cp != 'x'
|
|
&& *cp != 'X' && *cp != 's')
|
|
cp++;
|
|
/* don't support anything but 'd' */
|
|
if (*cp != 'd')
|
|
return(1);
|
|
*cp++; /* get rid of the 'd' */
|
|
break;
|
|
/* not suported by termcap, so not supported here */
|
|
case 'o': /* octal: no other formating is present */
|
|
case 'x': /* hex: no other formating is present */
|
|
case 'X': /* HEX: no other formating is present */
|
|
case 's': /* String: no other formating is present */
|
|
case 'c': /* binary character */
|
|
case 'l': /* strlen() operator */
|
|
case '=': /* equal operator */
|
|
case '>': /* greater than operator */
|
|
case '<': /* less than operator */
|
|
case '-': /* subtract operator */
|
|
case '*': /* multiply operator */
|
|
case '/': /* divide operator */
|
|
case 'm': /* modula operator */
|
|
case '&': /* bitwise and operator */
|
|
case '|': /* bitwise or operator */
|
|
case '^': /* bitwise xor operator */
|
|
case '~': /* bitwise not operator */
|
|
case 'A': /* logical and operator */
|
|
case 'O': /* logical or operator */
|
|
case '!': /* logical not operator */
|
|
return(1);
|
|
/* include the string "%A" where A = one of the following cases */
|
|
case 'd': /* decimal: no other formating is present */
|
|
case '%':
|
|
*bp++ = c;
|
|
*bp++ = c2;
|
|
break;
|
|
default: /* Bad % escape */
|
|
return (1);
|
|
}
|
|
}
|
|
else {
|
|
*bp++ = c;
|
|
}
|
|
}
|
|
*bp++ = '\0';
|
|
if (bp-buf > 1) {
|
|
if ((t->t_text = malloc(bp-buf+1)) == NULL)
|
|
return (2);
|
|
strncpy(t->t_text, buf, bp-buf);
|
|
t->t_size = bp-buf - 1;
|
|
} else {
|
|
t->t_text = NULL;
|
|
}
|
|
t->t_2nd = 0;
|
|
return (0);
|
|
}
|
|
#endif /* !HAVE_TERMCAP */
|
|
|
|
static int
|
|
cm_op(t) /* Cursor motion */
|
|
register struct tcap *t;
|
|
{
|
|
|
|
trace("cm", t);
|
|
lastInputLine = 0; /* no scroll stop line */
|
|
if (t->t_x >= 0 && t->t_x < CharsPerLine)
|
|
Dot.x = t->t_x;
|
|
if (t->t_y >= 0 && t->t_y < LinesPerScreen)
|
|
Dot.y = t->t_y;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
co_in(t) /* number of columns */
|
|
struct tcap *t;
|
|
{
|
|
trace("co", t);
|
|
if (userCharsPerLine < 1)
|
|
CharsPerLine = t->t_x;
|
|
return (0);
|
|
}
|
|
|
|
static int
|
|
cr_op(t) /* carriage return */
|
|
struct tcap *t;
|
|
{
|
|
trace("cr", t);
|
|
Dot.x = 0;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
cs_in(t) /* change scroll region */
|
|
struct tcap *t;
|
|
{
|
|
trace("cs", t);
|
|
return (cm_in(t)); /* Neat! It might even work */
|
|
}
|
|
|
|
static int
|
|
cs_op(t) /* change scroll region */
|
|
register struct tcap *t;
|
|
{
|
|
trace("cs", t);
|
|
if (t->t_y >= t->t_x || t->t_x >= LinesPerScreen)
|
|
return;
|
|
Dot.x = 0;
|
|
Dot.y = t->t_y;
|
|
TopLineOfScrollRegion = t->t_y;
|
|
BottomLineOfScrollRegion = t->t_x;
|
|
lastInputLine = 0; /* no scroll stop line */
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
dc_op(t) /* delete character */
|
|
struct tcap *t;
|
|
{
|
|
register struct line *l = screen[Dot.y];
|
|
register int dotx = Dot.x;
|
|
int len;
|
|
|
|
trace("dc", t);
|
|
if (l->changeposition > dotx)
|
|
l->changeposition = dotx;
|
|
if (dotx < l->length) {
|
|
l->length--;
|
|
len = l->length - dotx;
|
|
bcopy((char *)&l->prop[dotx+1], (char *)&l->prop[dotx], len);
|
|
l->prop[l->length] = 0 ;
|
|
bcopy(&l->body[dotx+1], &l->body[dotx], len);
|
|
l->body[l->length] = ' ' ;
|
|
}
|
|
l->end_of_changes = CharsPerLine ;
|
|
ChangeScreen();
|
|
}
|
|
|
|
static int
|
|
dl_op(t) /* delete line */
|
|
struct tcap *t;
|
|
{
|
|
register struct line **p, **bottom;
|
|
register struct line *old = screen[Dot.y];
|
|
|
|
trace("dl", t);
|
|
lastInputLine = 0; /* no scroll stop line */
|
|
bottom = &screen[BottomLineOfScrollRegion];
|
|
for (p = &screen[Dot.y]; p < bottom; p++)
|
|
*p = *(p+1);
|
|
*p = old;
|
|
clear_body(old, 0);
|
|
old->length = 0;
|
|
old->changeposition = 0;
|
|
old->end_of_changes = CharsPerLine ;
|
|
old->usedtobe = LinesPerScreen ;
|
|
ChangeScreen();
|
|
}
|
|
|
|
static int
|
|
do_op(t) /* down one line */
|
|
struct tcap *t;
|
|
{
|
|
trace("do", t);
|
|
if (PermanentModes & IgnoreNewlineAfterWrapMode) {
|
|
if (TemporaryModes & WrapJustHappenedMode) {
|
|
TemporaryModes &= ~WrapJustHappenedMode;
|
|
return;
|
|
}
|
|
}
|
|
if (Dot.y < LinesPerScreen - 1)
|
|
Dot.y++;
|
|
else {
|
|
sf_op(t);
|
|
}
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
ei_op(t) /* end insert mode */
|
|
struct tcap *t;
|
|
{
|
|
trace("ei", t);
|
|
PermanentModes &= ~InsertMode;
|
|
}
|
|
|
|
static int
|
|
el_op(t) /* end frame label definition mode */
|
|
struct tcap *t;
|
|
{
|
|
if (FLindex > 0) {
|
|
FrameLabel[FLindex] = '\0';
|
|
SetFrameLabel(FrameLabel);
|
|
FLindex = -1 ;
|
|
t = T+Ts;
|
|
t->t_op = prevInput;
|
|
}
|
|
}
|
|
|
|
static int
|
|
ke_op(t) /* leave keyboard transmit mode */
|
|
struct tcap *t;
|
|
{
|
|
trace("ke", t);
|
|
}
|
|
|
|
static int
|
|
ks_op(t) /* enter keyboard transmit mode */
|
|
struct tcap *t;
|
|
{
|
|
trace("ks", t);
|
|
}
|
|
|
|
static int
|
|
ho_op(t) /* home cursor */
|
|
struct tcap *t;
|
|
{
|
|
|
|
trace("ho", t);
|
|
lastInputLine = 0; /* no scroll stop line */
|
|
Dot.x = Dot.y = 0;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
ic_op(t) /* insert character */
|
|
struct tcap *t;
|
|
{
|
|
trace("ic", t);
|
|
TemporaryModes |= InsertMode;
|
|
}
|
|
|
|
static int
|
|
im_op(t) /* enter insert mode */
|
|
struct tcap *t;
|
|
{
|
|
trace("im", t);
|
|
PermanentModes |= InsertMode;
|
|
}
|
|
|
|
static int
|
|
le_op(t) /* cursor left */
|
|
struct tcap *t;
|
|
{
|
|
trace("le", t);
|
|
if (Dot.x > 0)
|
|
Dot.x--;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
li_in(t) /* number of lines */
|
|
struct tcap *t;
|
|
{
|
|
trace("li", t);
|
|
if (userLinesPerScreen < 1)
|
|
LinesPerScreen = t->t_x;
|
|
return (0);
|
|
}
|
|
|
|
static int
|
|
ll_op(t) /* last line first column */
|
|
struct tcap *t;
|
|
{
|
|
trace("ll", t);
|
|
Dot.x = 0;
|
|
Dot.y = LinesPerScreen - 1;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
lm_op(t) /* label mode input */
|
|
register struct tcap *t;
|
|
{
|
|
trace("lm", t);
|
|
if (FLindex < 0) return;
|
|
if (FLindex + t->t_size >= MaxCharsPerLine)
|
|
t->t_size = MaxCharsPerLine - FLindex;
|
|
if (t->t_size > 0) {
|
|
strncpy(&FrameLabel[FLindex], t->t_text, (int)t->t_size);
|
|
FLindex += t->t_size;
|
|
}
|
|
}
|
|
|
|
static int
|
|
mb_op(t) /* enable blink */
|
|
struct tcap *t;
|
|
{
|
|
trace("mb", t);
|
|
PermanentModes |= BlinkMode;
|
|
}
|
|
|
|
static int
|
|
md_op(t) /* enter bold mode */
|
|
struct tcap *t;
|
|
{
|
|
trace("md", t);
|
|
PermanentModes |= BoldMode;
|
|
}
|
|
|
|
static int
|
|
me_op(t) /* turn off attributes */
|
|
struct tcap *t;
|
|
{
|
|
trace("me", t);
|
|
PermanentModes &= ~(Attributes);
|
|
}
|
|
|
|
static int
|
|
mr_op(t) /* enter reverse video */
|
|
struct tcap *t;
|
|
{
|
|
trace("mr", t);
|
|
PermanentModes |= ReverseVideoMode;
|
|
}
|
|
|
|
static int
|
|
nd_op(t) /* cursor right */
|
|
struct tcap *t;
|
|
{
|
|
trace("nd", t);
|
|
if (Dot.x < (CharsPerLine - 1))
|
|
Dot.x++;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
nl_op(t) /* newline */
|
|
struct tcap *t;
|
|
{
|
|
trace("nl", t);
|
|
if (PermanentModes & IgnoreNewlineAfterWrapMode) {
|
|
if (TemporaryModes & WrapJustHappenedMode) {
|
|
TemporaryModes &= ~WrapJustHappenedMode;
|
|
return;
|
|
}
|
|
}
|
|
if (Dot.y < LinesPerScreen - 1)
|
|
Dot.y++;
|
|
else {
|
|
sf_op(t);
|
|
}
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
rc_op(t) /* restore cursor */
|
|
struct tcap *t;
|
|
{
|
|
trace("rc", t);
|
|
Dot = SavedCursor;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
sc_op(t) /* save cursor */
|
|
struct tcap *t;
|
|
{
|
|
trace("sc", t);
|
|
SavedCursor = Dot;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
se_op(t) /* leave stand-out */
|
|
struct tcap *t;
|
|
{
|
|
trace("se", t);
|
|
PermanentModes &= ~StandOutMode;
|
|
}
|
|
|
|
static int
|
|
so_op(t) /* enter stand-out */
|
|
struct tcap *t;
|
|
{
|
|
trace("so", t);
|
|
PermanentModes |= StandOutMode;
|
|
}
|
|
|
|
static int
|
|
sf_op(t) /* scroll forwards */
|
|
struct tcap *t;
|
|
{
|
|
register struct line **p, **bottom;
|
|
register struct line *old;
|
|
static int SFrecur = 0;
|
|
|
|
trace("sf", t);
|
|
/*
|
|
* When sf is "\n", nl_op won't be called, so we emulate
|
|
* it's actions here (beware of recursion).
|
|
*/
|
|
if (ScrollNLKludge && !SFrecur) {
|
|
SFrecur++; nl_op(t); SFrecur--;
|
|
return (1); /* XXX */
|
|
}
|
|
p = &screen[TopLineOfScrollRegion];
|
|
if (PageMode && *p == lastInputLine) {
|
|
PageFull++; /* can't scroll this line */
|
|
return (0);
|
|
}
|
|
ScrollSaveLine(*p);
|
|
bottom = &screen[BottomLineOfScrollRegion];
|
|
p = &screen[TopLineOfScrollRegion];
|
|
old = *p;
|
|
for (; p < bottom; p++)
|
|
*p = *(p+1);
|
|
*p = old;
|
|
clear_body(old, 0);
|
|
old->length = 0;
|
|
old->changeposition = 0;
|
|
old->end_of_changes = CharsPerLine ;
|
|
old->usedtobe = LinesPerScreen;
|
|
ChangeScreen();
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
sl_op(t) /* start defining new frame label */
|
|
register struct tcap *t;
|
|
{
|
|
trace("sl", t);
|
|
FLindex = 0;
|
|
t = T+Ts;
|
|
prevInput = t->t_op;
|
|
t->t_op = lm_op;
|
|
}
|
|
|
|
static int
|
|
sr_op(t) /* scroll reverse */
|
|
struct tcap *t;
|
|
{
|
|
register struct line **p, **top;
|
|
register struct line *old;
|
|
|
|
trace("sr", t);
|
|
lastInputLine = 0; /* no scroll stop line */
|
|
top = &screen[TopLineOfScrollRegion];
|
|
p = &screen[BottomLineOfScrollRegion];
|
|
old = *p;
|
|
for (; p > top; p--)
|
|
*p = *(p-1);
|
|
*p = old;
|
|
clear_body(old, 0);
|
|
old->length = 0;
|
|
old->changeposition = 0;
|
|
old->end_of_changes = CharsPerLine ;
|
|
old->usedtobe = LinesPerScreen;
|
|
ChangeScreen();
|
|
}
|
|
|
|
static int
|
|
ta_op(t) /* tab */
|
|
struct tcap *t;
|
|
{
|
|
trace("ta", t);
|
|
Dot.x = (Dot.x & ~07) + 010;
|
|
if (Dot.x >= CharsPerLine - 1)
|
|
Dot.x = CharsPerLine - 1;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
te_op(t) /* end use of termcap */
|
|
struct tcap *t;
|
|
{
|
|
trace("te", t);
|
|
if (PrevPageMode != -1) {
|
|
PageMode = PrevPageMode;
|
|
PrevPageMode = -1;
|
|
}
|
|
}
|
|
|
|
static int
|
|
ti_op(t) /* begin use of termcap */
|
|
{
|
|
trace("ti", t);
|
|
/*
|
|
* Turn off page mode when using termcap.
|
|
*/
|
|
if (PrevPageMode == -1) {
|
|
PrevPageMode = PageMode;
|
|
PageMode = 0;
|
|
}
|
|
}
|
|
|
|
static int
|
|
ue_op(t) /* end underline */
|
|
struct tcap *t;
|
|
{
|
|
trace("ue", t);
|
|
PermanentModes &= ~UnderlineMode;
|
|
}
|
|
|
|
static int
|
|
up_op(t) /* cursor up */
|
|
struct tcap *t;
|
|
{
|
|
trace("up", t);
|
|
if (Dot.y > 0)
|
|
Dot.y--;
|
|
else /* vi will never do this, but some ll caps may */
|
|
Dot.y = LinesPerScreen - 1;
|
|
MoveCursor();
|
|
}
|
|
|
|
static int
|
|
us_op(t) /* start underline */
|
|
struct tcap *t;
|
|
{
|
|
trace("us", t);
|
|
PermanentModes |= UnderlineMode;
|
|
}
|
|
|
|
static int
|
|
vb_op(t) /* visibile bell */
|
|
struct tcap *t;
|
|
{
|
|
trace("bl", t);
|
|
VisibleBell();
|
|
}
|
|
|
|
static int
|
|
xn_in(t)
|
|
struct tcap *t;
|
|
{
|
|
trace("xn", t);
|
|
if (t->t_x) PermanentModes |= IgnoreNewlineAfterWrapMode;
|
|
return (0);
|
|
}
|
|
|
|
/* These capabilities are numeric or boolean - they dont have ops */
|
|
#define am_op NULL
|
|
#define bs_op NULL
|
|
#define co_op NULL
|
|
#define li_op NULL
|
|
#define pc_op NULL
|
|
#define xn_op NULL
|
|
|
|
/* These capabilities are strings that dont need initialization */
|
|
#define al_in NULL
|
|
#define bc_in NULL
|
|
#define bl_in NULL
|
|
#define cd_in NULL
|
|
#define ce_in NULL
|
|
#define cl_in NULL
|
|
#define cr_in NULL
|
|
#define dc_in NULL
|
|
#define dl_in NULL
|
|
#define do_in NULL
|
|
#define ei_in NULL
|
|
#define ke_in NULL
|
|
#define ks_in NULL
|
|
#define ho_in NULL
|
|
#define ic_in NULL
|
|
#define im_in NULL
|
|
#define le_in NULL
|
|
#define ll_in NULL
|
|
#define mb_in NULL
|
|
#define md_in NULL
|
|
#define me_in NULL
|
|
#define mr_in NULL
|
|
#define nd_in NULL
|
|
#define nl_in NULL
|
|
#define pc_in NULL
|
|
#define rc_in NULL
|
|
#define sc_in NULL
|
|
#define se_in NULL
|
|
#define sf_in NULL
|
|
#define so_in NULL
|
|
#define sr_in NULL
|
|
#define ta_in NULL
|
|
#define ue_in NULL
|
|
#define up_in NULL
|
|
#define us_in NULL
|
|
|
|
#define s string
|
|
#define n num
|
|
#define b bool
|
|
|
|
struct tcap T[] = {
|
|
/*
|
|
* key ty op in text deftx sz in tmp tf
|
|
* x xi xl y yi yl r n B D 2
|
|
*/
|
|
{"AL", s, AL_op, cs_in, NULL, NULL, 0, 0, NULL, 0},/* 0 */
|
|
{"DL", s, DL_op, cs_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"DC", s, DC_op, cs_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"DO", s, DO_op, DO_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"IC", s, IC_op, cs_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"LE", s, LE_op, LE_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"RI", s, RI_op, RI_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"UP", s, UP_op, UP_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"al", s, al_op, al_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"am", b, am_op, am_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"bc", s, bc_op, bc_in, NULL, "\10", 0, 0, NULL, 0},/* 10 */
|
|
{"bl", s, bl_op, bl_in, NULL, "\7", 0, 0, NULL, 0},
|
|
{"cd", s, cd_op, cd_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"ce", s, ce_op, ce_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"cl", s, cl_op, cl_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"cm", s, cm_op, cm_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"co", n, co_op, co_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"cr", s, cr_op, cr_in, NULL, "\015", 0, 0, NULL, 0},
|
|
{"cs", s, cs_op, cs_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"dc", s, dc_op, dc_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"dl", s, dl_op, dl_in, NULL, NULL, 0, 0, NULL, 0},/* 20 */
|
|
{"do", s, do_op, do_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"ei", s, ei_op, ei_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"el", s, el_op, NULL, NULL,"\033\\",0, 0, NULL, 0}, /* end label */
|
|
{"ke", s, ke_op, ke_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"ks", s, ks_op, ks_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"ho", s, ho_op, ho_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"ic", s, ic_op, ic_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"im", s, im_op, im_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"le", s, le_op, le_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"li", n, li_op, li_in, NULL, NULL, 0, 0, NULL, 0},/* 30 */
|
|
{"ll", s, ll_op, ll_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"lm", s, lm_op, NULL, NULL, NULL, 0, 0, NULL, 0}, /* label mode input */
|
|
{"mb", s, mb_op, mb_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"md", s, md_op, md_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"me", s, me_op, me_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"mr", s, mr_op, mr_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"nd", s, nd_op, nd_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"nl", s, nl_op, nl_in, NULL, "\012", 0, 0, NULL, 0},
|
|
{"pc", s, pc_op, pc_in, NULL, "\200", 0, 0, NULL, 0},
|
|
{"rc", s, rc_op, rc_in, NULL, NULL, 0, 0, NULL, 0},/* 40 */
|
|
{"sc", s, sc_op, sc_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"se", s, se_op, se_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"sf", s, sf_op, sf_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"sl", s, sl_op, NULL, NULL,"\033]l",0, 0, NULL, 0}, /* start label */
|
|
{"so", s, so_op, so_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"sr", s, sr_op, sr_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"ta", s, ta_op, ta_in, NULL, "\011", 0, 0, NULL, 0}, /* XXX */
|
|
{"te", s, te_op, NULL, NULL, NULL, 0, 0, NULL, 0},
|
|
{"ti", s, ti_op, NULL, NULL, NULL, 0, 0, NULL, 0},
|
|
{"ue", s, ue_op, ue_in, NULL, NULL, 0, 0, NULL, 0},/* 50 */
|
|
{"up", s, up_op, up_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"us", s, us_op, us_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"vb", s, vb_op, NULL, NULL, NULL, 0, 0, NULL, 0},
|
|
{"xn", b, xn_op, xn_in, NULL, NULL, 0, 0, NULL, 0},
|
|
{"", s, showc, NULL, NULL, NULL, 0, 0, NULL, 0},
|
|
};
|
|
|
|
/* T[Ts] is a special case - its the display-character operation */
|
|
int Ts = (sizeof T)/(sizeof T[0]) - 1;
|