PD Terminfo/Curses (part 7 of 11)
sources at genrad.UUCP
sources at genrad.UUCP
Thu Dec 20 14:28:02 AEST 1984
This is part of a distribution of a public domain version of terminfo/curses
It is a rather large distribution, so I have broken it up into 11 modules
(each less than 64K long.) Each shar format module should end with the line
"exit". This code is completely public domain, originally written by Pavel
Curtis of Cornell University. This version has some small improvements and
bug fixes.
This unit contains:
more source units of the library.
Part 8 will be
more source units of the library.
----------------- cut here ----------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
if test ! -d =src
then
echo 'Making directory "=src"'
mkdir =src
fi
echo 'x - =src/lib_getch.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_getch.c
X/*********************************************************************
* COPYRIGHT NOTICE *
**********************************************************************
* This software is copyright (C) 1982 by Pavel Curtis *
* *
* Permission is granted to reproduce and distribute *
* this file by any means so long as no fee is charged *
* above a nominal handling fee and so long as this *
* notice is always included in the copies. *
* *
* Other rights are reserved except as explicitly granted *
* by written permission of the author. *
* Pavel Curtis *
* Computer Science Dept. *
* 405 Upson Hall *
* Cornell University *
* Ithaca, NY 14853 *
* *
* Ph- (607) 256-4934 *
* *
* Pavel.Cornell at Udel-Relay (ARPAnet) *
* decvax!cornell!pavel (UUCPnet) *
*********************************************************************/
X/*
** lib_getch.c
**
** The routine getch().
**
** $Log: RCS/lib_getch.v $
* Revision 2.1 82/10/25 14:47:29 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:45:19 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_getch.v Revision 2.1 82/10/25 14:47:29 pavel Exp$";
#include <signal.h>
#include "curses.h"
#include "curses.priv.h"
#define nextc() (SP->_backcnt > 0 ? SP->_backbuf[--SP->_backcnt] \
: getc(SP->_ifp))
#define putback(ch) SP->_backbuf[SP->_backcnt++] = ch
wgetch(win)
WINDOW *win;
{
bool setHere = FALSE; /* cbreak mode was set here */
short ch; /* 'short' because of keypad codes */
short kgetch();
#ifdef TRACE
if (_tracing)
_tracef("wgetch(%o) called", win);
#endif
if (! win->_scroll && (win->_flags & _FULLWIN)
&& win->_curx == win->_maxx
&& win->_cury == win->_maxy)
return(ERR);
#ifdef FIONREAD
if (win->_nodelay)
{
long count;
ioctl(fileno(SP->_ifp), FIONREAD, &count);
if (! count)
return(-1);
}
#endif
if (SP->_echo && ! (SP->_raw || SP->_cbreak))
{
cbreak();
setHere = TRUE;
}
if (win->_use_keypad)
ch = kgetch();
else
ch = nextc();
if (SP->_echo && ch < 0400) /* ch < 0400 => not a keypad key */
{
mvwaddch(curscr, win->_begy + win->_cury,
win->_begx + win->_curx, ch | win->_attrs);
waddch(win, ch | win->_attrs);
}
if (setHere)
nocbreak();
return(ch);
}
X/*
** short
** kgetch()
**
** Get an input character, but take care of keypad sequences, returning
** an appropriate code when one matches the input. After each character
** is received, set a one-second alarm call. If no more of the sequence
** is received by the time the alarm goes off, pass through the sequence
** gotten so far.
**
*/
static bool alarmed;
static
short
kgetch()
{
struct try *ptr;
char ch;
char buffer[10]; /* Assume no sequences longer than 10 */
char *bufp = buffer;
int (*oldsig)();
int sigalrm();
ptr = SP->_keytry;
oldsig = signal(SIGALRM, sigalrm);
alarmed = FALSE;
do
{
ch = nextc();
if (ch != EOF) /* getc() returns EOF on error, too */
*(bufp++) = ch;
if (alarmed)
break;
while (ptr != NULL && ptr->ch != ch)
ptr = ptr->sibling;
if (ptr != NULL)
{
if (ptr->value != NULL)
{
alarm(0);
signal(SIGALRM, oldsig);
return(ptr->value);
}
else
{
ptr = ptr->child;
alarm(1);
}
}
} while (ptr != NULL);
alarm(0);
signal(SIGALRM, oldsig);
while (--bufp > buffer)
putback(*bufp);
return(*bufp);
}
static
sigalrm()
{
alarmed = TRUE;
signal(SIGALRM, sigalrm);
}
//go.sysin dd *
echo 'x - =src/lib_getstr.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_getstr.c
X/*********************************************************************
* COPYRIGHT NOTICE *
**********************************************************************
* This software is copyright (C) 1982 by Pavel Curtis *
* *
* Permission is granted to reproduce and distribute *
* this file by any means so long as no fee is charged *
* above a nominal handling fee and so long as this *
* notice is always included in the copies. *
* *
* Other rights are reserved except as explicitly granted *
* by written permission of the author. *
* Pavel Curtis *
* Computer Science Dept. *
* 405 Upson Hall *
* Cornell University *
* Ithaca, NY 14853 *
* *
* Ph- (607) 256-4934 *
* *
* Pavel.Cornell at Udel-Relay (ARPAnet) *
* decvax!cornell!pavel (UUCPnet) *
*********************************************************************/
X/*
** lib_getstr.c
**
** The routine wgetstr().
**
** $Log: RCS/lib_getstr.v $
* Revision 2.1 82/10/25 14:47:33 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:45:39 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_getstr.v Revision 2.1 82/10/25 14:47:33 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
#include "unctrl.h"
#define backspace() { \
mvwaddstr(curscr, win->_begy + win->_cury, \
win->_begx + win->_curx, "\b \b");\
waddstr(win, "\b \b"); \
fputs("\b \b", SP->_ofp); \
fflush(SP->_ofp); \
}
wgetstr(win,str)
WINDOW *win;
char *str;
{
bool oldnl, oldecho, oldraw, oldcbreak;
char erasec;
char killc;
char *oldstr;
#ifdef TRACE
if (_tracing)
_tracef("wgetstr(%o,%o) called", win, str);
#endif
oldnl = SP->_nl;
oldecho = SP->_echo;
oldraw = SP->_raw;
oldcbreak = SP->_cbreak;
nl();
noecho();
noraw();
cbreak();
erasec = erasechar();
killc = killchar();
oldstr = str;
while ((*str = getc(SP->_ifp)) != ERR && *str != '\n')
{
if (*str == erasec)
{
if (str > oldstr)
{
str--;
backspace();
if (*str < ' ' || *str == '\177')
backspace();
}
}
else if (*str == killc)
{
while (str > oldstr)
{
str--;
backspace();
if (*str < ' ' || *str == '\177')
backspace();
}
}
else
{
mvwaddstr(curscr, win->_begy + win->_cury,
win->_begx + win->_curx, unctrl(*str));
waddstr(win, unctrl(*str));
fputs(unctrl(*str), SP->_ofp);
fflush(SP->_ofp);
str++;
}
}
if (! oldnl)
nonl();
if (oldecho)
echo();
if (oldraw)
raw();
if (! oldcbreak)
nocbreak();
if (*str == ERR)
{
*str = '\0';
return(ERR);
}
*str = '\0';
#ifdef TRACE
if (_tracing)
_tracef("\twgetstr returns %s", oldstr);
#endif
return(OK);
}
//go.sysin dd *
echo 'x - =src/lib_initscr.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_initscr.c
X/*********************************************************************
* COPYRIGHT NOTICE *
**********************************************************************
* This software is copyright (C) 1982 by Pavel Curtis *
* *
* Permission is granted to reproduce and distribute *
* this file by any means so long as no fee is charged *
* above a nominal handling fee and so long as this *
* notice is always included in the copies. *
* *
* Other rights are reserved except as explicitly granted *
* by written permission of the author. *
* Pavel Curtis *
* Computer Science Dept. *
* 405 Upson Hall *
* Cornell University *
* Ithaca, NY 14853 *
* *
* Ph- (607) 256-4934 *
* *
* Pavel.Cornell at Udel-Relay (ARPAnet) *
* decvax!cornell!pavel (UUCPnet) *
*********************************************************************/
X/*
** lib_initscr.c
**
** The routine initscr().
**
** $Log: RCS/lib_initscr.v $
* Revision 2.1 82/10/25 14:47:36 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:45:54 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_initscr.v Revision 2.1 82/10/25 14:47:36 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
WINDOW *
initscr()
{
#ifdef TRACE
_init_trace();
if (_tracing)
_tracef("initscr() called");
#endif
if (newterm(getenv("TERM"), stdout) == ERR)
return(ERR);
else
return(stdscr);
}
//go.sysin dd *
echo 'x - =src/lib_insch.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_insch.c
X/*********************************************************************
* COPYRIGHT NOTICE *
**********************************************************************
* This software is copyright (C) 1982 by Pavel Curtis *
* *
* Permission is granted to reproduce and distribute *
* this file by any means so long as no fee is charged *
* above a nominal handling fee and so long as this *
* notice is always included in the copies. *
* *
* Other rights are reserved except as explicitly granted *
* by written permission of the author. *
* Pavel Curtis *
* Computer Science Dept. *
* 405 Upson Hall *
* Cornell University *
* Ithaca, NY 14853 *
* *
* Ph- (607) 256-4934 *
* *
* Pavel.Cornell at Udel-Relay (ARPAnet) *
* decvax!cornell!pavel (UUCPnet) *
*********************************************************************/
X/*
** lib_insch.c
**
** The routine winsch().
**
** $Log: RCS/lib_insch.v $
* Revision 2.1 82/10/25 14:47:39 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:46:02 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_insch.v Revision 2.1 82/10/25 14:47:39 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
winsch(win, c)
WINDOW *win;
char c;
{
chtype *temp1, *temp2;
chtype *end;
#ifdef TRACE
if (_tracing)
_tracef("winsch(%o,'%c') called", win, c);
#endif
end = &win->_line[win->_cury][win->_curx];
temp1 = &win->_line[win->_cury][win->_maxx];
temp2 = temp1 - 1;
while (temp1 > end)
*temp1-- = *temp2--;
*temp1 = c | win->_attrs;
win->_lastchar[win->_cury] = win->_maxx;
if (win->_firstchar[win->_cury] == _NOCHANGE
|| win->_firstchar[win->_cury] > win->_curx)
win->_firstchar[win->_cury] = win->_curx;
}
//go.sysin dd *
echo 'x - =src/lib_insertln.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_insertln.c
X/*********************************************************************
* COPYRIGHT NOTICE *
**********************************************************************
* This software is copyright (C) 1982 by Pavel Curtis *
* *
* Permission is granted to reproduce and distribute *
* this file by any means so long as no fee is charged *
* above a nominal handling fee and so long as this *
* notice is always included in the copies. *
* *
* Other rights are reserved except as explicitly granted *
* by written permission of the author. *
* Pavel Curtis *
* Computer Science Dept. *
* 405 Upson Hall *
* Cornell University *
* Ithaca, NY 14853 *
* *
* Ph- (607) 256-4934 *
* *
* Pavel.Cornell at Udel-Relay (ARPAnet) *
* decvax!cornell!pavel (UUCPnet) *
*********************************************************************/
X/*
** lib_insertln.c
**
** The routine winsertln().
**
** $Log: RCS/lib_insertln.v $
* Revision 2.1 82/10/25 14:47:44 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:46:12 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_insertln.v Revision 2.1 82/10/25 14:47:44 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
winsertln(win)
WINDOW *win;
{
chtype *temp, *end;
int y;
#ifdef TRACE
if (_tracing)
_tracef("winsertln(%o) called", win);
#endif
temp = win->_line[win->_regbottom];
win->_firstchar[win->_cury] = 0;
win->_lastchar[win->_cury] = win->_maxx;
for (y = win->_regbottom; y > win->_cury; y--)
{
win->_line[y] = win->_line[y-1];
win->_firstchar[y] = 0;
win->_lastchar[y] = win->_maxx;
}
win->_line[win->_cury] = temp;
for (end = &temp[win->_maxx]; temp <= end; temp++)
*temp = ' ' | win->_attrs;
}
//go.sysin dd *
echo 'x - =src/lib_longname.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_longname.c
X/*********************************************************************
* COPYRIGHT NOTICE *
**********************************************************************
* This software is copyright (C) 1982 by Pavel Curtis *
* *
* Permission is granted to reproduce and distribute *
* this file by any means so long as no fee is charged *
* above a nominal handling fee and so long as this *
* notice is always included in the copies. *
* *
* Other rights are reserved except as explicitly granted *
* by written permission of the author. *
* Pavel Curtis *
* Computer Science Dept. *
* 405 Upson Hall *
* Cornell University *
* Ithaca, NY 14853 *
* *
* Ph- (607) 256-4934 *
* *
* Pavel.Cornell at Udel-Relay (ARPAnet) *
* decvax!cornell!pavel (UUCPnet) *
*********************************************************************/
X/*
** lib_longname.c
**
** The routine longname().
**
** $Log: RCS/lib_longname.v $
* Revision 2.1 82/10/25 14:47:49 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:46:21 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_longname.v Revision 2.1 82/10/25 14:47:49 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
char *
longname()
{
char *ptr;
#ifdef TRACE
if (_tracing)
_tracef("longname() called");
#endif
for (ptr = ttytype + strlen(ttytype); ptr > ttytype; ptr--)
if (*ptr == '|')
return(ptr + 1);
return(ttytype);
}
//go.sysin dd *
echo 'x - =src/lib_move.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_move.c
X/*********************************************************************
* COPYRIGHT NOTICE *
**********************************************************************
* This software is copyright (C) 1982 by Pavel Curtis *
* *
* Permission is granted to reproduce and distribute *
* this file by any means so long as no fee is charged *
* above a nominal handling fee and so long as this *
* notice is always included in the copies. *
* *
* Other rights are reserved except as explicitly granted *
* by written permission of the author. *
* Pavel Curtis *
* Computer Science Dept. *
* 405 Upson Hall *
* Cornell University *
* Ithaca, NY 14853 *
* *
* Ph- (607) 256-4934 *
* *
* Pavel.Cornell at Udel-Relay (ARPAnet) *
* decvax!cornell!pavel (UUCPnet) *
*********************************************************************/
X/*
** lib_move.c
**
** The routine wmove().
**
** $Log: RCS/lib_move.v $
* Revision 2.1 82/10/25 14:47:51 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:46:31 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_move.v Revision 2.1 82/10/25 14:47:51 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
wmove(win, y, x)
WINDOW *win;
int y, x;
{
#ifdef TRACE
if (_tracing)
_tracef("wmove(%o,%d,%d) called", win, y, x);
#endif
if (0 <= x && x <= win->_maxx &&
win->_regtop <= y && y <= win->_regbottom)
{
win->_curx = x;
win->_cury = y;
return(OK);
}
else
return(ERR);
}
//go.sysin dd *
echo 'x - =src/lib_mvcur.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_mvcur.c
X/*********************************************************************
* COPYRIGHT NOTICE *
**********************************************************************
* This software is copyright (C) 1982 by Pavel Curtis *
* *
* Permission is granted to reproduce and distribute *
* this file by any means so long as no fee is charged *
* above a nominal handling fee and so long as this *
* notice is always included in the copies. *
* *
* Other rights are reserved except as explicitly granted *
* by written permission of the author. *
* Pavel Curtis *
* Computer Science Dept. *
* 405 Upson Hall *
* Cornell University *
* Ithaca, NY 14853 *
* *
* Ph- (607) 256-4934 *
* *
* Pavel.Cornell at Udel-Relay (ARPAnet) *
* decvax!cornell!pavel (UUCPnet) *
*********************************************************************/
X/*
**
** lib_mvcur.c
**
** mvcur() and its subroutines
**
** $Log: RCS/lib_mvcur.v $
* Revision 2.1 82/10/25 14:47:54 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:46:40 pavel
* Beta-one Test Release
*
**
** Revisions needed:
** implement c_save instead of multiple tputs() calls
** routine revisions
*/
static char RCSid[] =
"$Header: RCS/lib_mvcur.v Revision 2.1 82/10/25 14:47:54 pavel Exp$";
#include "term.h"
#include "curses.h"
#include "curses.priv.h"
#define BUFSIZE 128 /* size of strategy buffer */
struct Sequence
{
int vec[BUFSIZE], /* vector of operations */
*end, /* end of vector */
cost; /* cost of vector */
};
X/*
** #define
** Make_seq_best(s1, s2)
**
** Make_seq_best() swaps the values
** of the pointers if s1->cost > s2->cost.
*/
#define Make_seq_best(s1, s2) \
if (s1->cost > s2->cost) \
{ \
struct Sequence *temp; \
\
temp = s1; \
s1 = s2; \
s2 = temp; \
}
XFILE *out_file; /* pointer to output file */
static int c_count; /* used for counting tputs output */
X/*rev c_save not yet used
static char *c_save; /* used for saving tputs output */
#define INFINITY 1000 /* biggest, impossible sequence cost */
#define NUM_OPS 16 /* num. term. control sequences */
#define NUM_NPARM 9 /* num. ops wo/ parameters */
/* operator indexes into op_info */
#define CARRIAGE_RETURN 0 /* watch out for nl mapping */
#define CURS_DOWN 1
#define CURS_HOME 2
#define CURS_LEFT 3
#define CURS_RIGHT 4
#define CURS_TO_LL 5
#define CURS_UP 6
#define TAB 7
#define BACK_TAB 8
#define ROW_ADDR 9
#define COL_ADDR 10
#define P_DOWN_CURS 11
#define P_LEFT_CURS 12
#define P_RIGHT_CURS 13
#define P_UP_CURS 14
#define CURS_ADDR 15
static bool loc_init = FALSE; /* set if op_info is init'ed */
static bool rel_ok; /* set if we really know where we are */
X/*
* op_info[NUM_OPS]
*
* op_info[] contains for operations with no parameters
* the cost of the operation. These ops should be first in the array.
* For operations with parameters, op_info[] contains
* the negative of the number of parameters.
*/
static int op_info[NUM_OPS] =
{
0, /* carriage_return */
0, /* cursor_down */
0, /* cursor_home */
0, /* cursor_left */
0, /* cursor_right */
0, /* cursor_to_ll */
0, /* cursor_up */
0, /* tab */
0, /* back_tab */
-1, /* row_address */
-1, /* column_address */
-1, /* parm_down_cursor */
-1, /* parm_left_cursor */
-1, /* parm_right_cursor */
-1, /* parm_up_cursor */
-2 /* cursor_address */
};
X/*
**
** mvcur(oldrow, oldcol, newrow, newcol)
**
** mvcur() optimally moves the cursor from the position
** specified by (oldrow, oldcol) to (newrow, newcol). If
** (oldrow, oldcol) == (-1, -1), mvcur() does not use relative
** cursor motions. If the coordinates are otherwise
** out of bounds, it mods them into range.
**
** Revisions needed:
** eat_newline_glitch, auto_right_margin
*/
mvcur(oldrow, oldcol, newrow, newcol)
int oldrow, oldcol,
newrow, newcol;
{
struct Sequence seqA, seqB, /* allocate work structures */
col0seq, /* sequence to get from col0 to nc */
*best, /* best sequence so far */
*try; /* next try */
#ifdef TRACE
if (_tracing)
_tracef("mvcur(%d,%d,%d,%d) called",
oldrow, oldcol, newrow, newcol);
#endif
update_ops(); /* make sure op_info[] is current */
if (oldrow < 0 || oldcol < 0)
rel_ok = FALSE; /* relative ops ok? */
else
{
rel_ok = TRUE;
oldrow %= lines; /* mod values into range */
oldcol %= columns;
}
newrow %= lines;
newcol %= columns;
best = &seqA;
try = &seqB;
/* try out direct cursor addressing */
zero_seq(best);
add_op(best, CURS_ADDR, newrow, newcol);
/* try out independent row/column addressing */
if (rel_ok)
{
zero_seq(try);
row(try, oldrow, newrow);
column(try, oldcol, newcol);
Make_seq_best(best, try);
}
zero_seq(&col0seq); /* store seq. to get from c0 to nc */
column(&col0seq, 0, newcol);
if(col0seq.cost < INFINITY) /* can get from col0 to newcol */
{
/* try out homing and then row/column */
if (! rel_ok || newcol < oldcol || newrow < oldrow)
{
zero_seq(try);
add_op(try, CURS_HOME, 1);
row(try, 0, newrow);
add_seq(try, &col0seq);
Make_seq_best(best, try);
}
/* try out homing to last line and then row/column */
if (! rel_ok || newcol < oldcol || newrow > oldrow)
{
zero_seq(try);
add_op(try, CURS_TO_LL, 1);
row(try, lines - 1, newrow);
add_seq(try, &col0seq);
Make_seq_best(best, try);
}
}
#ifdef TRACE
if (_tracing)
_tracef("\tmvcur: result follows");
#endif
out_seq(best);
#ifdef TRACE
if (_tracing)
_tracef("\tmvcur: end of result");
#endif
}
X/*
** row(outseq, oldrow, newrow)
**
** row() adds the best sequence for moving
** the cursor from oldrow to newrow to seq.
** row() considers row_address, parm_up/down_cursor
** and cursor_up/down.
*/
static
row(outseq, orow, nrow)
int orow, nrow; /* old, new cursor locations */
struct Sequence *outseq; /* where to put the output */
{
struct Sequence seqA, seqB,
*best, /* best sequence so far */
*try; /* next try */
int parm_cursor, one_step;
best = &seqA;
try = &seqB;
if (nrow == orow)
return;
if (nrow < orow)
{
parm_cursor = P_UP_CURS;
one_step = CURS_UP;
}
else
{
parm_cursor = P_DOWN_CURS;
one_step = CURS_DOWN;
}
/* try out direct row addressing */
zero_seq(best);
add_op(best, ROW_ADDR, nrow);
/* try out paramaterized up or down motion */
if (rel_ok)
{
zero_seq(try);
add_op(try, parm_cursor, abs(orow - nrow));
Make_seq_best(best, try);
}
/* try getting there one step at a time... */
if (rel_ok)
{
zero_seq(try);
add_op(try, one_step, abs(orow-nrow));
Make_seq_best(best, try);
}
add_seq(outseq, best);
}
X/*
** column(outseq, oldcol, newcol)
**
** column() adds the best sequence for moving
** the cursor from oldcol to newcol to outseq.
** column() considers column_address, parm_left/right_cursor,
** simp_col(), and carriage_return followed by simp_col().
*/
static
column(outseq, ocol, ncol)
struct Sequence *outseq; /* where to put the output */
int ocol, ncol; /* old, new cursor column */
{
struct Sequence seqA, seqB,
*best, *try;
int parm_cursor; /* set to either parm_up/down_cursor */
best = &seqA;
try = &seqB;
if (ncol == ocol)
return;
if (ncol < ocol)
parm_cursor = P_LEFT_CURS;
else
parm_cursor = P_RIGHT_CURS;
/* try out direct column addressing */
zero_seq(best);
add_op(best, COL_ADDR, ncol);
/* try carriage_return then simp_col() */
if (! rel_ok || (ncol < ocol))
{
zero_seq(try);
add_op(try, CARRIAGE_RETURN, 1);
simp_col(try, 0, ncol);
Make_seq_best(best, try);
}
if (rel_ok)
{
/* try out paramaterized left or right motion */
zero_seq(try);
add_op(try, parm_cursor, abs(ocol - ncol));
Make_seq_best(best, try);
/* try getting there with simp_col() */
zero_seq(try);
simp_col(try, ocol, ncol);
Make_seq_best(best, try);
}
add_seq(outseq, best);
}
X/*
** simp_col(outseq, oldcol, newcol)
**
** simp_col() adds the best simple sequence for getting
** from oldcol to newcol to outseq.
** simp_col() considers (back_)tab and cursor_left/right.
**
** Revisions needed:
** Simp_col asssumes that the cost of a (back_)tab
** is less then the cost of one-stepping to get to the same column.
** Should sometimes use overprinting instead of cursor_right.
*/
static
simp_col(outseq, oc, nc)
struct Sequence *outseq; /* place to put sequence */
int oc, nc; /* old column, new column */
{
struct Sequence seqA, seqB, tabseq,
*best, *try;
int mytab, tabs, onepast,
one_step, opp_step;
if (! rel_ok)
{
outseq->cost = INFINITY;
return;
}
if (oc == nc)
return;
best = &seqA;
try = &seqB;
if (oc < nc)
{
mytab = TAB;
if (init_tabs > 0 && op_info[TAB] < INFINITY)
{
tabs = nc / init_tabs - oc / init_tabs;
onepast = ((nc / init_tabs) + 1) * init_tabs;
if (tabs)
oc = onepast - init_tabs; /* consider it done */
}
else
tabs = 0;
one_step = CURS_RIGHT;
opp_step = CURS_LEFT;
}
else
{
mytab = BACK_TAB;
if (init_tabs > 0 && op_info[BACK_TAB] < INFINITY)
{
tabs = oc / init_tabs - nc / init_tabs;
onepast = ((nc - 1) / init_tabs) * init_tabs;
if (tabs)
oc = onepast + init_tabs; /* consider it done */
}
else
tabs = 0;
one_step = CURS_LEFT;
opp_step = CURS_RIGHT;
}
/* tab as close as possible to nc */
zero_seq(&tabseq);
add_op(&tabseq, mytab, tabs);
/* try extra tab and backing up */
zero_seq(best);
if (onepast >= 0 && onepast < columns)
{
add_op(best, mytab, 1);
add_op(best, opp_step, abs(onepast - nc));
}
else
best->cost = INFINITY; /* make sure of next swap */
/* try stepping to nc */
zero_seq(try);
add_op(try, one_step, abs(nc - oc));
Make_seq_best(best, try);
if (tabseq.cost < INFINITY)
add_seq(outseq, &tabseq);
add_seq(outseq, best);
}
X/*
** zero_seq(seq)
** add_seq(seq1, seq2)
** out_seq(seq)
**
** zero_seq() empties seq.
** add_seq() adds seq1 to seq2.
** out_seq() outputs a sequence.
*/
static
zero_seq(seq)
struct Sequence *seq;
{
seq->end = seq->vec;
seq->cost = 0;
}
static
add_seq(seq1, seq2)
struct Sequence *seq1, *seq2;
{
int *vptr;
if(seq1->cost >= INFINITY || seq2->cost >= INFINITY)
seq1->cost = INFINITY;
else
{
vptr = seq2->vec;
while (vptr != seq2->end)
*(seq1->end++) = *(vptr++);
seq1->cost += seq2->cost;
}
}
static
out_seq(seq)
struct Sequence *seq;
{
int *opptr, prm[9], ps, p, op, outc();
int count;
char *sequence();
if (seq->cost >= INFINITY)
return;
for (opptr = seq->vec; opptr < seq->end; opptr++)
{
op = *opptr; /* grab operator */
ps = -op_info[op];
if(ps > 0) /* parameterized */
{
for (p = 0; p < ps; p++) /* fill in needed parms */
prm[p] = *(++opptr);
tputs(tparm(sequence(op),
prm[0], prm[1], prm[2], prm[3], prm[4],
prm[5], prm[6], prm[7], prm[8]), 1, outc);
}
else
{
count = *(++opptr);
/*rev should save tputs output instead of mult calls */
while (count--) /* do count times */
tputs(sequence(op), 1, outc);
}
}
}
X/*
** update_ops()
**
** update_ops() makes sure that
** the op_info[] array is updated and initializes
** the cost array for SP if needed.
*/
static
update_ops()
{
if (SP) /* SP structure exists */
{
int op;
out_file = SP->_ofp; /* set output file pointer */
if (! SP->_costinit) /* this term not yet assigned costs */
{
loc_init = FALSE; /* if !SP in the future, new term */
init_costs(SP->_costs); /* fill term costs */
SP->_costinit = TRUE;
}
for (op = 0; op < NUM_NPARM; op++)
op_info[op] = SP->_costs[op]; /* set up op_info */
/* check for newline that might be mapped... */
if (SP->_nlmapping && index(sequence(CURS_DOWN), '\n'))
op_info[CURS_DOWN] = INFINITY;
}
else
{
out_file = stdout;
if (! loc_init) /* using local costs */
{
loc_init = TRUE;
init_costs(op_info); /* set up op_info */
}
/* check for newline that might be mapped... */
if (index(sequence(CURS_DOWN), '\n'))
op_info[CURS_DOWN] = INFINITY;
}
}
X/*
** init_costs(costs)
**
** init_costs() fills the array costs[NUM_NPARM]
** with costs calculated by doing tputs() calls.
*/
static
init_costs(costs)
int costs[];
{
int i, countc();
for (i = 0; i < NUM_NPARM; i++)
if(sequence(i) != (char *) 0)
{
#ifdef UNDEFINED
if (_tracing)
_tracef("\tinit_costs: pricing %d: '%s'", i, sequence(i));
#endif
c_count = 0;
tputs(sequence(i), 1, countc);
costs[i] = c_count;
}
else
costs[i] = INFINITY;
}
X/*
** countc()
** outc(c)
** savec(c)
**
** countc() increments global var c_count.
** outc() outputs a single character.
** savec() saves c in *c_save and increments c_save and c_count.
*/
static
countc()
{
c_count++;
}
static
outc(c)
char c;
{
fputc(c, out_file);
}
X/*rev not yet needed
static
savec(c)
char c;
{
*(c_save++) = c;
c_count++;
}
*/
X/*
** add_op(seq, op, p0, p1, ... , p8)
**
** add_op() adds the operator op and the appropriate
** number of paramaters to seq. It also increases the
** cost appropriately.
** if op has no parameters, p0 is taken to be a count.
*/
static
add_op(seq, op, p0, p1, p2, p3, p4, p5, p6, p7, p8)
struct Sequence *seq;
int op, p0, p1, p2, p3, p4, p5, p6, p7, p8;
{
int num_ps, p;
#ifdef UNDEFINED
if (_tracing)
_tracef("\tadd_op(%o,%d,%d,%d) called", seq, op, p0, p1);
#endif
num_ps = - op_info[op]; /* get parms or -cost */
*(seq->end++) = op;
if (num_ps == (- INFINITY) || sequence(op) == (char *) 0)
seq->cost = INFINITY;
else
if (num_ps <= 0) /* no parms, -cost */
{
seq->cost -= p0 * num_ps; /* ADD count * cost */
*(seq->end++) = p0;
}
else
{
int pms[9];
pms[0] = p0; pms[1] = p1; pms[2] = p2;
pms[3] = p3; pms[4] = p4; pms[5] = p5;
pms[6] = p6; pms[7] = p7; pms[8] = p8;
for(p = 0; p < num_ps; p++)
*(seq->end++) = pms[p];
c_count = 0;
tputs(tparm(sequence(op), p0, p1, p2, p3, p4, p5, p6, p7, p8),
1, countc);
seq->cost += c_count;
}
}
X/*
** char *
** sequence(op)
**
** sequence() returns a pointer to the op's
** terminal control sequence.
*/
static char *
sequence(op)
int op;
{
switch(op)
{
case CARRIAGE_RETURN:
return (carriage_return);
case CURS_DOWN:
return (cursor_down);
case CURS_HOME:
return (cursor_home);
case CURS_LEFT:
return (cursor_left);
case CURS_RIGHT:
return (cursor_right);
case CURS_TO_LL:
return (cursor_to_ll);
case CURS_UP:
return (cursor_up);
case TAB:
return (tab);
case BACK_TAB:
return (back_tab);
case ROW_ADDR:
return (row_address);
case COL_ADDR:
return (column_address);
case P_DOWN_CURS:
return (parm_down_cursor);
case P_LEFT_CURS:
return (parm_left_cursor);
case P_RIGHT_CURS:
return (parm_right_cursor);
case P_UP_CURS:
return (parm_up_cursor);
case CURS_ADDR:
return (cursor_address);
default:
return ((char *) 0);
}
}
//go.sysin dd *
echo 'x - =src/lib_mvwin.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_mvwin.c
X/*********************************************************************
* COPYRIGHT NOTICE *
**********************************************************************
* This software is copyright (C) 1982 by Pavel Curtis *
* *
* Permission is granted to reproduce and distribute *
* this file by any means so long as no fee is charged *
* above a nominal handling fee and so long as this *
* notice is always included in the copies. *
* *
* Other rights are reserved except as explicitly granted *
* by written permission of the author. *
* Pavel Curtis *
* Computer Science Dept. *
* 405 Upson Hall *
* Cornell University *
* Ithaca, NY 14853 *
* *
* Ph- (607) 256-4934 *
* *
* Pavel.Cornell at Udel-Relay (ARPAnet) *
* decvax!cornell!pavel (UUCPnet) *
*********************************************************************/
X/*
** lib_mvwin.c
**
** The routine mvwin().
**
** $Log: RCS/lib_mvwin.v $
* Revision 2.1 82/10/25 14:48:10 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:47:03 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_mvwin.v Revision 2.1 82/10/25 14:48:10 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
mvwin(win, by, bx)
WINDOW *win;
int by, bx;
{
#ifdef TRACE
if (_tracing)
_tracef("mvwin(%o,%d,%d) called", win, by, bx);
#endif
if (by + win->_maxy > LINES -1 || bx + win->_maxx > COLS - 1)
return(ERR);
win->_begy = by;
win->_begx = bx;
touchwin(win);
return(OK);
}
//go.sysin dd *
echo 'x - =src/lib_newterm.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_newterm.c
X/*********************************************************************
* COPYRIGHT NOTICE *
**********************************************************************
* This software is copyright (C) 1982 by Pavel Curtis *
* *
* Permission is granted to reproduce and distribute *
* this file by any means so long as no fee is charged *
* above a nominal handling fee and so long as this *
* notice is always included in the copies. *
* *
* Other rights are reserved except as explicitly granted *
* by written permission of the author. *
* Pavel Curtis *
* Computer Science Dept. *
* 405 Upson Hall *
* Cornell University *
* Ithaca, NY 14853 *
* *
* Ph- (607) 256-4934 *
* *
* Pavel.Cornell at Udel-Relay (ARPAnet) *
* decvax!cornell!pavel (UUCPnet) *
*********************************************************************/
X/*
** lib_newterm.c
**
** The newterm() function.
**
** $Log: RCS/lib_newterm.v $
* Revision 2.1 82/10/25 14:48:14 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:47:11 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_newterm.v Revision 2.1 82/10/25 14:48:14 pavel Exp$";
#include <signal.h>
#include <stdio.h>
#include "curses.h"
#include "term.h"
#include "curses.priv.h"
struct screen *
newterm(term, fp)
char *term;
XFILE *fp;
{
int errret;
int tstp();
#ifdef TRACE
_init_trace();
if (_tracing)
_tracef("newterm(%s,%o) called", term, fp);
#endif
if (setupterm(term, fileno(fp), &errret) != 1)
return(ERR);
if ((SP = (struct screen *) malloc(sizeof *SP)) == NULL)
return(ERR);
if (fp == stdout)
{
SP->_ofp = stdout;
SP->_ifp = stdin;
}
else
{
SP->_ofp = fp;
SP->_ifp = fp;
}
SP->_term = cur_term;
SP->_cursrow = -1;
SP->_curscol = -1;
SP->_keytry = UNINITIALISED;
SP->_nl = TRUE;
SP->_raw = FALSE;
SP->_cbreak = FALSE;
SP->_echo = TRUE;
SP->_nlmapping = TRUE;
SP->_costinit = FALSE;
LINES = lines;
COLS = columns;
if (enter_ca_mode)
putp(enter_ca_mode);
if ((newscr = newwin(lines, columns, 0, 0)) == ERR)
return(ERR);
if ((curscr = newwin(lines, columns, 0, 0)) == ERR)
return(ERR);
SP->_newscr = newscr;
SP->_curscr = curscr;
newscr->_clear = TRUE;
curscr->_clear = FALSE;
signal(SIGTSTP, tstp);
if (stdscr == NULL)
if ((stdscr = newwin(lines, columns, 0, 0)) == ERR)
return(ERR);
#ifdef TRACE
if (_tracing)
_tracef("\tnewterm returns %o", SP);
#endif
return(SP);
}
//go.sysin dd *
echo 'x - =src/lib_newwin.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_newwin.c
X/*********************************************************************
* COPYRIGHT NOTICE *
**********************************************************************
* This software is copyright (C) 1982 by Pavel Curtis *
* *
* Permission is granted to reproduce and distribute *
* this file by any means so long as no fee is charged *
* above a nominal handling fee and so long as this *
* notice is always included in the copies. *
* *
* Other rights are reserved except as explicitly granted *
* by written permission of the author. *
* Pavel Curtis *
* Computer Science Dept. *
* 405 Upson Hall *
* Cornell University *
* Ithaca, NY 14853 *
* *
* Ph- (607) 256-4934 *
* *
* Pavel.Cornell at Udel-Relay (ARPAnet) *
* decvax!cornell!pavel (UUCPnet) *
*********************************************************************/
X/*
** lib_newwin.c
**
** The routines newwin(), subwin() and their dependent
**
** $Log: RCS/lib_newwin.v $
* Revision 2.1 82/10/25 14:48:18 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:47:18 pavel
* Beta-one Test Release
*
**
*/
#include "term.h"
#include "curses.h"
#include "curses.priv.h"
short *calloc();
WINDOW *malloc();
static WINDOW *makenew();
WINDOW *
newwin(num_lines, num_columns, begy, begx)
int num_lines, num_columns, begy, begx;
{
WINDOW *win;
chtype *ptr;
int i, j;
#ifdef TRACE
if (_tracing)
_tracef("newwin(%d,%d,%d,%d) called", num_lines, num_columns, begy, begx);
#endif
if (num_lines == 0)
num_lines = lines - begy;
if (num_columns == 0)
num_columns = columns - begx;
if ((win = makenew(num_lines, num_columns, begy, begx)) == ERR)
return(ERR);
for (i = 0; i < num_lines; i++)
{
if ((win->_line[i] = (chtype *) calloc(num_columns, sizeof(chtype)))
== NULL)
{
for (j = 0; j < i; j++)
cfree(win->_line[j]);
cfree(win->_firstchar);
cfree(win->_lastchar);
cfree(win->_line);
cfree(win);
return(ERR);
}
else
for (ptr = win->_line[i]; ptr < win->_line[i] + num_columns; )
*ptr++ = ' ';
}
#ifdef TRACE
if (_tracing)
_tracef("\tnewwin: returned window is %o", win);
#endif
return(win);
}
WINDOW *
subwin(orig, num_lines, num_columns, begy, begx)
WINDOW *orig;
int num_lines, num_columns, begy, begx;
{
WINDOW *win;
int i, j, k;
#ifdef TRACE
if (_tracing)
_tracef("subwin(%d,%d,%d,%d) called", num_lines, num_columns, begy, begx);
#endif
/*
** make sure window fits inside the original one
*/
if (begy < orig->_begy || begx < orig->_begx
|| begy + num_lines > orig->_maxy
|| begx + num_columns > orig->_maxx)
return(ERR);
if (num_lines == 0)
num_lines = orig->_maxy - orig->_begy - begy;
if (num_columns == 0)
num_columns = orig->_maxx - orig->_begx - begx;
if ((win = makenew(num_lines, num_columns, begy, begx)) == ERR)
return(ERR);
j = orig->_begy + begy;
k = orig->_begx + begx;
for (i = 0; i < num_lines; i++)
win->_line[i] = &orig->_line[j++][k];
win->_flags = _SUBWIN;
#ifdef TRACE
if (_tracing)
_tracef("\tsubwin: returned window is %o", win);
#endif
return(win);
}
static WINDOW *
makenew(num_lines, num_columns, begy, begx)
int num_lines, num_columns, begy, begx;
{
int i;
WINDOW *win;
if ((win = (WINDOW *) malloc(sizeof(WINDOW))) == NULL)
return ERR;
if ((win->_line = (chtype **) calloc(num_lines, sizeof (chtype *)))
== NULL)
{
cfree(win);
return(ERR);
}
if ((win->_firstchar = calloc(num_lines, sizeof(short))) == NULL)
{
cfree(win);
cfree(win->_line);
return(ERR);
}
if ((win->_lastchar = calloc(num_lines, sizeof(short))) == NULL)
{
cfree(win);
cfree(win->_line);
cfree(win->_firstchar);
return(ERR);
}
if ((win->_numchngd = calloc(num_lines, sizeof(short))) == NULL)
{
cfree(win);
cfree(win->_line);
cfree(win->_firstchar);
cfree(win->_lastchar);
return(ERR);
}
win->_curx = 0;
win->_cury = 0;
win->_maxy = num_lines - 1;
win->_maxx = num_columns - 1;
win->_begy = begy;
win->_begx = begx;
win->_flags = 0;
win->_attrs = A_NORMAL;
win->_clear = (num_lines == lines && num_columns == columns);
win->_scroll = FALSE;
win->_leave = FALSE;
win->_use_keypad = FALSE;
win->_use_meta = FALSE;
win->_nodelay = FALSE;
win->_regtop = 0;
win->_regbottom = num_lines - 1;
for (i = 0; i < num_lines; i++)
{
win->_firstchar[i] = win->_lastchar[i] = _NOCHANGE;
win->_numchngd[i] = 0;
}
if (begx + num_columns == columns)
{
win->_flags |= _ENDLINE;
if (begx == 0 && num_lines == lines && begy == 0)
win->_flags |= _FULLWIN;
if (begy + num_lines == lines)
win->_flags |= _SCROLLWIN;
}
return(win);
}
//go.sysin dd *
echo 'x - =src/lib_options.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_options.c
X/*********************************************************************
* COPYRIGHT NOTICE *
**********************************************************************
* This software is copyright (C) 1982 by Pavel Curtis *
* *
* Permission is granted to reproduce and distribute *
* this file by any means so long as no fee is charged *
* above a nominal handling fee and so long as this *
* notice is always included in the copies. *
* *
* Other rights are reserved except as explicitly granted *
* by written permission of the author. *
* Pavel Curtis *
* Computer Science Dept. *
* 405 Upson Hall *
* Cornell University *
* Ithaca, NY 14853 *
* *
* Ph- (607) 256-4934 *
* *
* Pavel.Cornell at Udel-Relay (ARPAnet) *
* decvax!cornell!pavel (UUCPnet) *
*********************************************************************/
X/*
** lib_options.c
**
** The routines to handle option setting.
**
** $Log: RCS/lib_options.v $
* Revision 2.1 82/10/25 14:48:24 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:47:45 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_options.v Revision 2.1 82/10/25 14:48:24 pavel Exp$";
#include "term.h"
#include "curses.h"
#include "curses.priv.h"
static
outc(ch)
char ch;
{
putc(ch, SP->_ofp);
}
idlok(win, flag)
WINDOW *win;
int flag;
{
#ifdef TRACE
if (_tracing)
_tracef("idlok(%o,%d) called", win, flag);
#endif
if ((insert_line && delete_line)
#ifdef UNIMPLEMENTED
|| (change_scroll_region)
#endif
)
curscr->_idlok = flag;
}
clearok(win, flag)
WINDOW *win;
int flag;
{
#ifdef TRACE
if (_tracing)
_tracef("clearok(%o,%d) called", win, flag);
#endif
if (win == curscr)
newscr->_clear = flag;
else
win->_clear = flag;
}
leaveok(win, flag)
WINDOW *win;
int flag;
{
#ifdef TRACE
if (_tracing)
_tracef("leaveok(%o,%d) called", win, flag);
#endif
win->_leave = flag;
}
scrollok(win, flag)
WINDOW *win;
int flag;
{
#ifdef TRACE
if (_tracing)
_tracef("scrollok(%o,%d) called", win, flag);
#endif
win->_scroll = flag;
}
nodelay(win, flag)
WINDOW *win;
int flag;
{
#ifdef TRACE
if (_tracing)
_tracef("nodelay(%o,%d) called", win, flag);
#endif
win->_nodelay = flag;
}
keypad(win, flag)
WINDOW *win;
int flag;
{
#ifdef TRACE
if (_tracing)
_tracef("keypad(%o,%d) called", win, flag);
#endif
win->_use_keypad = flag;
if (flag && keypad_xmit)
tputs(keypad_xmit, 1, outc);
else if (! flag && keypad_local)
tputs(keypad_local, 1, outc);
if (SP->_keytry == UNINITIALISED)
init_keytry();
}
meta(win, flag)
WINDOW *win;
int flag;
{
#ifdef TRACE
if (_tracing)
_tracef("meta(%o,%d) called", win, flag);
#endif
win->_use_meta = flag;
if (flag && meta_on)
tputs(meta_on, 1, outc);
else if (! flag && meta_off)
tputs(meta_off, 1, outc);
}
X/*
** init_keytry()
**
** Construct the try for the current terminal's keypad keys.
**
*/
static struct try *newtry;
static
init_keytry()
{
newtry = NULL;
add_to_try(key_backspace, KEY_BACKSPACE);
add_to_try(key_catab, KEY_CATAB);
add_to_try(key_clear, KEY_CLEAR);
add_to_try(key_ctab, KEY_CTAB);
add_to_try(key_dc, KEY_DC);
add_to_try(key_dl, KEY_DL);
add_to_try(key_down, KEY_DOWN);
add_to_try(key_eic, KEY_EIC);
add_to_try(key_eol, KEY_EOL);
add_to_try(key_eos, KEY_EOS);
add_to_try(key_f0, KEY_F(0));
add_to_try(key_f1, KEY_F(1));
add_to_try(key_f2, KEY_F(2));
add_to_try(key_f3, KEY_F(3));
add_to_try(key_f4, KEY_F(4));
add_to_try(key_f5, KEY_F(5));
add_to_try(key_f6, KEY_F(6));
add_to_try(key_f7, KEY_F(7));
add_to_try(key_f8, KEY_F(8));
add_to_try(key_f9, KEY_F(9));
add_to_try(key_f10, KEY_F(10));
add_to_try(key_home, KEY_HOME);
add_to_try(key_ic, KEY_IC);
add_to_try(key_il, KEY_IL);
add_to_try(key_left, KEY_LEFT);
add_to_try(key_npage, KEY_NPAGE);
add_to_try(key_ppage, KEY_PPAGE);
add_to_try(key_right, KEY_RIGHT);
add_to_try(key_sf, KEY_SF);
add_to_try(key_sr, KEY_SR);
add_to_try(key_stab, KEY_STAB);
add_to_try(key_up, KEY_UP);
SP->_keytry = newtry;
}
add_to_try(str, code)
char *str;
short code;
{
static bool out_of_memory = FALSE;
struct try *ptr, *savedptr;
struct try *malloc();
if (! str || out_of_memory)
return;
if (newtry != NULL)
{
ptr = newtry;
for (;;)
{
while (ptr->ch != *str && ptr->sibling != NULL)
ptr = ptr->sibling;
if (ptr->ch == *str)
{
if (*(++str))
{
if (ptr->child != NULL)
ptr = ptr->child;
else
break;
}
else
{
ptr->value = code;
return;
}
}
else
{
if ((ptr->sibling = malloc(sizeof *ptr)) == NULL)
{
out_of_memory = TRUE;
return;
}
savedptr = ptr = ptr->sibling;
ptr->child = ptr->sibling = NULL;
ptr->ch = *str++;
ptr->value = NULL;
break;
}
} /* end for (;;) */
}
else /* newtry == NULL :: First sequence to be added */
{
savedptr = ptr = newtry = malloc(sizeof *ptr);
if (ptr == NULL)
{
out_of_memory = TRUE;
return;
}
ptr->child = ptr->sibling = NULL;
ptr->ch = *(str++);
ptr->value = NULL;
}
/* at this point, we are adding to the try. ptr->child == NULL */
while (*str)
{
ptr->child = malloc(sizeof *ptr);
ptr = ptr->child;
if (ptr == NULL)
{
out_of_memory = TRUE;
ptr = savedptr;
while (ptr != NULL)
{
savedptr = ptr->child;
free(ptr);
ptr = savedptr;
}
return;
}
ptr->child = ptr->sibling = NULL;
ptr->ch = *(str++);
ptr->value = NULL;
}
ptr->value = code;
return;
}
//go.sysin dd *
exit
More information about the Mod.sources
mailing list