PD Terminfo/Curses (part 8 of 11)
sources at genrad.UUCP
sources at genrad.UUCP
Thu Dec 20 22:29:11 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 library modules
Part 9 will be
the last of the library, and the start of the terminal data files.
----------------- 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_doupdate.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_doupdate.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_doupdate.c
*
* The routine doupdate() and its dependents
*
* $Log: lib_doupdate.c,v $
* Revision 3.1 84/12/13 11:20:28 john
* Revisions by Mark Horton
*
* Revision 2.1 82/10/25 14:47:05 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:44:33 pavel
* Beta-one Test Release
*
*
*/
static char RCSid[] =
"$Header: lib_doupdate.c,v 3.1 84/12/13 11:20:28 john Exp $";
#include <signal.h>
#include "curses.h"
#include "curses.priv.h"
#include "term.h"
#define GoTo(row,col) mvcur(SP->_cursrow, SP->_curscol, row, col); \
SP->_cursrow = row; \
SP->_curscol = col;
#define PutAttrChar(ch) if (curscr->_attrs != (ch & A_ATTRIBUTES)) \
{ \
curscr->_attrs = ch & A_ATTRIBUTES; \
vidputs(curscr->_attrs, outc); \
} \
putc(ch & A_CHARTEXT, SP->_ofp);
#define PutChar(ch) if (!auto_right_margin || \
SP->_cursrow != lines - 1 || \
SP->_curscol != columns - 1) \
{ \
PutAttrChar(ch); \
SP->_curscol++; \
if (SP->_curscol >= columns) \
if (auto_right_margin) \
{ \
SP->_curscol = 0; \
SP->_cursrow++; \
} \
else \
SP->_curscol--; \
}
outc(ch)
char ch;
{
putc(ch, SP->_ofp);
}
doupdate()
{
int i;
int (*oldsig)();
#ifdef TRACE
if (_tracing)
_tracef("doupdate() called");
#endif
oldsig = signal(SIGTSTP, SIG_IGN);
if (curscr->_clear)
{
ClrUpdate(curscr);
curscr->_clear = FALSE;
GoTo(curscr->_cury, curscr->_curx);
}
else
{
if (newscr->_clear)
{
ClrUpdate(newscr);
newscr->_clear = FALSE;
}
else if (curscr->_idlok)
IdlUpdate();
else
NoIdlUpdate();
for (i = 0; i < lines; i++)
{
newscr->_firstchar[i] = _NOCHANGE;
newscr->_lastchar[i] = _NOCHANGE;
newscr->_numchngd[i] = 0;
}
curscr->_curx = newscr->_curx;
curscr->_cury = newscr->_cury;
GoTo(curscr->_cury, curscr->_curx);
}
fflush(SP->_ofp);
signal(SIGTSTP, oldsig);
}
X/*
** ClrUpdate(scr)
**
** Update by clearing and redrawing the entire screen.
**
*/
static
ClrUpdate(scr)
WINDOW *scr;
{
int i, j;
int lastNonBlank;
ClearScreen();
for (i=0; i < lines; i++)
{
lastNonBlank = columns - 1;
while (scr->_line[i][lastNonBlank] == ' ')
lastNonBlank--;
if (i == lines && lastNonBlank == columns - 1)
lastNonBlank--;
for (j=0; j <= lastNonBlank; j++)
{
PutAttrChar(scr->_line[i][j]);
}
if (! auto_right_margin || lastNonBlank < columns - 1)
{
SP->_cursrow = i;
SP->_curscol = lastNonBlank < 0 ? 0 : lastNonBlank;
GoTo(i + 1, 0);
}
}
if (scr != curscr)
{
for (i=0; i < LINES; i++)
for (j=0; j < COLS; j++)
curscr->_line[i][j] = scr->_line[i][j];
}
}
X/*
** NoIdlUpdate()
**
** Update screen without using Insert/Delete Line capabilities
**
*/
static
NoIdlUpdate()
{
int i;
#ifdef TRACE
if (_tracing)
_tracef("NoIdlUpdate() called");
#endif
for (i=0; i < lines; i++)
if (newscr->_numchngd[i])
TransformLine(i);
}
X/*
** IdlUpdate()
**
** Update screen using Insert/Delete Line capabilities
**
*/
#define UNCHANGED(n) (newscr->_numchngd[n] <= columns/10 \
|| newscr->_lastchar[n] \
- newscr->_firstchar[n] <= columns/10)
static
IdlUpdate()
{
int firstLine, lastLine, thisLine;
#ifdef TRACE
if (_tracing)
_tracef("IdlUpdate() called");
#endif
firstLine = -1;
for (thisLine = 0; thisLine < lines; thisLine++)
{
if (UNCHANGED(thisLine))
{
if (firstLine != -1)
{
lastLine = thisLine - 1;
Gosling(firstLine, lastLine);
firstLine = -1;
}
if (newscr->_firstchar[thisLine] != _NOCHANGE)
TransformLine(thisLine);
}
else if (firstLine == -1)
firstLine = thisLine;
}
if (firstLine != -1)
Gosling(firstLine, lines - 1);
}
X/*
** TransformLine(lineno)
**
** Call either IDcTransformLine or NoIDcTransformLine to do the
** update, depending upon availability of insert/delete character.
*/
static
TransformLine(lineno)
int lineno;
{
if ( (insert_character || (enter_insert_mode && exit_insert_mode))
&& delete_character)
IDcTransformLine(lineno);
else
NoIDcTransformLine(lineno);
}
X/*
** NoIDcTransformLine(lineno)
**
** Transform the given line in curscr to the one in newscr, without
** using Insert/Delete Character.
**
** firstChar = position of first different character in line
** lastChar = position of last different character in line
**
** overwrite all characters between firstChar and lastChar.
**
*/
static
NoIDcTransformLine(lineno)
int lineno;
{
register int firstChar, lastChar;
register chtype *newLine = newscr->_line[lineno];
register chtype *oldLine = curscr->_line[lineno];
register int k;
#ifdef TRACE
if (_tracing)
_tracef("NoIDcTransformLine(%d) called", lineno);
#endif
firstChar = 0;
while (firstChar < columns
&& newLine[firstChar] == oldLine[firstChar])
firstChar++;
if (firstChar >= columns)
return;
lastChar = columns - 1;
while (lastChar > firstChar && newLine[lastChar] == oldLine[lastChar])
lastChar--;
GoTo(lineno, firstChar);
for (k=firstChar; k <= lastChar; k++)
{
PutChar(newLine[k]);
oldLine[k] = newLine[k];
}
}
X/*
** IDcTransformLine(lineno)
**
** Transform the given line in curscr to the one in newscr, using
** Insert/Delete Character.
**
** firstChar = position of first different character in line
** oLastChar = position of last different character in old line
** nLastChar = position of last different character in new line
**
** move to firstChar
** overwrite chars up to min(oLastChar, nLastChar)
** if oLastChar < nLastChar
** insert newLine[oLastChar+1..nLastChar]
** else
** delete oLastChar - nLastChar spaces
*/
static
IDcTransformLine(lineno)
int lineno;
{
int firstChar, oLastChar, nLastChar;
chtype *newLine = newscr->_line[lineno];
chtype *oldLine = curscr->_line[lineno];
int k, n;
#ifdef TRACE
if (_tracing)
_tracef("IDcTransformLine(%d) called", lineno);
#endif
firstChar = 0;
while (firstChar < columns && newLine[firstChar] == oldLine[firstChar])
firstChar++;
if (firstChar >= columns)
return;
oLastChar = columns - 1;
while (oLastChar > firstChar && oldLine[oLastChar] == ' ')
oLastChar--;
nLastChar = columns - 1;
while (nLastChar > firstChar && newLine[nLastChar] == ' ')
nLastChar--;
while (newLine[nLastChar] == oldLine[oLastChar])
{
nLastChar--;
oLastChar--;
}
n = min(oLastChar, nLastChar);
GoTo(lineno, firstChar);
for (k=firstChar; k <= n; k++)
PutChar(newLine[k]);
if (oLastChar < nLastChar)
InsStr(&newLine[k], nLastChar - oLastChar);
else if (oLastChar > nLastChar)
DelChar(oLastChar - nLastChar);
for (k=firstChar; k < columns; k++)
oldLine[k] = newLine[k];
}
X/*
** Gosling(firstLine, lastLine)
**
** Change the given range of lines on curscr into the same lines
** on newscr, using Gosling's Algorithm.
*/
static short lineCost[MAXLINES][MAXLINES];
static short lineOps[MAXLINES][MAXLINES];
static short lineDels[MAXLINES];
static short lineIRs[MAXLINES];
#define INSERT 1
#define DELETE 2
#define REPLACE 3
static
Gosling(firstLine, lastLine)
int firstLine, lastLine;
{
int i, count;
#ifdef TRACE
if (_tracing)
_tracef("Gosling(%d,%d) called", firstLine, lastLine);
#endif
Goscost(firstLine, lastLine - firstLine + 1);
for (i=0; i <= lastLine - firstLine + 1; i++)
lineDels[i] = lineIRs[i] = 0;
Gosdraw(lastLine - firstLine + 1, lastLine - firstLine + 1);
count = 0;
for (i = lastLine - firstLine + 1; i > 0; i--)
{
if (lineDels[i] == DELETE)
count++;
else if (count)
{
DelLine(count, firstLine + i, lastLine);
count = 0;
}
}
if (count)
DelLine(count, firstLine, lastLine);
for (i = 1; i <= lastLine - firstLine + 1; i++)
{
switch (lineIRs[i])
{
case REPLACE:
TransformLine(firstLine + i - 1);
break;
case INSERT:
InsLine(firstLine + i - 1, lastLine);
break;
default:
/* do nothing */
break;
}
}
}
#define RPLCOST(old,new) (oHash[old] == nHash[new] ? 0 : columns)
static
Goscost(lineno, length)
int lineno, length;
{
int i, j, cost;
int ILcost, DLcost;
long nHash[MAXLINES], oHash[MAXLINES];
long HashFn();
#ifdef TRACE
if (_tracing)
_tracef("Goscost(lineno=%d,length=%d) called", lineno, length);
#endif
ILcost = (insert_line ? strlen(insert_line) : 9999) + columns;
DLcost = (delete_line ? strlen(delete_line) : 9999);
for (i=1; i <= length; i++)
{
nHash[i] = HashFn(newscr->_line[lineno + i - 1]);
oHash[i] = HashFn(curscr->_line[lineno + i - 1]);
}
lineCost[0][0] = 0;
for (i=1; i <= length; i++)
{
lineCost[i][0] = lineCost[i-1][0] + DLcost;
lineOps[i][0] = DELETE;
lineCost[0][i] = lineCost[0][i-1] + ILcost;
lineOps[0][i] = INSERT;
}
for (i=1; i <= length; i++)
{
for (j=1; j <= length; j++)
{
lineCost[i][j] = lineCost[i-1][j-1] + RPLCOST(i, j);
lineOps[i][j] = REPLACE;
cost = lineCost[i][j-1] + ILcost;
if (cost < lineCost[i][j])
{
lineCost[i][j] = cost;
lineOps[i][j] = INSERT;
}
cost = lineCost[i-1][j] + DLcost;
if (cost < lineCost[i][j])
{
lineCost[i][j] = cost;
lineOps[i][j] = DELETE;
}
}
}
return(lineCost[columns][columns]);
}
X/*
** _PrintCosts(length)
**
** Print out the cost matrix. Called only from sdb.
**
**
** _DumpNewscr(first, last)
**
** Print the specified range of lines from newscr. Called only from sdb.
**
**
** _DumpCurscr(first, last)
**
** Print the specified range of lines from curscr. Called only from sdb.
**
*/
_PrintCosts(length)
int length;
{
int i, j;
for (i=0; i <= length; i++)
{
for (j=0; j <= length; j++)
{
printf("%5d/%d", lineCost[i][j], lineOps[i][j]);
}
putchar('\n');
}
fflush(stdout);
}
_DumpNewscr(first, last)
int first, last;
{
int i, j;
for (i=first; i <= last; i++)
{
for (j=0; j < columns; j++)
putchar(newscr->_line[i][j]);
putchar('\n');
}
}
_DumpCurscr(first, last)
int first, last;
{
int i, j;
for (i=first; i <= last; i++)
{
for (j=0; j < columns; j++)
putchar(curscr->_line[i][j]);
putchar('\n');
}
}
long
HashFn(line)
chtype *line;
{
int i = 0;
long hash = 0;
while(i < columns && (line[i] | A_CHARTEXT) == ' ')
i++;
for (; i+1 < columns; i += 2)
hash += (line[i] << 8) + line[i+1];
return (hash);
}
static
Gosdraw(i, j)
int i, j;
{
if (i == 0 && j == 0)
return;
switch (lineOps[i][j])
{
case INSERT:
Gosdraw(i, j-1);
lineIRs[j] = INSERT;
break;
case DELETE:
lineDels[i] = DELETE;
Gosdraw(i-1, j);
break;
case REPLACE:
Gosdraw(i-1, j-1);
lineIRs[j] = REPLACE;
break;
}
}
X/*
** ClearScreen()
**
** Clear the physical screen and put cursor at home
**
*/
static
ClearScreen()
{
if (clear_screen)
{
tputs(clear_screen, 1, outc);
SP->_cursrow = SP->_curscol = 0;
}
else if (clr_eos)
{
SP->_cursrow = SP->_curscol = -1;
GoTo(0,0);
tputs(clr_eos, 1, outc);
}
else if (clr_eol)
{
SP->_cursrow = SP->_curscol = -1;
while (SP->_cursrow < lines)
{
GoTo(SP->_cursrow, 0);
tputs(clr_eol, 1, outc);
}
GoTo(0,0);
}
}
X/*
** InsStr(line, count)
**
** Insert the count characters pointed to by line.
**
*/
InsStr(line, count)
chtype *line;
int count;
{
#ifdef TRACE
if (_tracing)
_tracef("InsStr(%o,%d) called", line, count);
#endif
if (enter_insert_mode && exit_insert_mode)
{
tputs(enter_insert_mode, 1, outc);
while (count)
{
PutChar(*line);
line++;
count--;
}
tputs(exit_insert_mode, 1, outc);
}
else if (parm_ich)
{
tputs(tparm(parm_ich, count), 1, outc);
while (count)
{
PutChar(*line);
line++;
count--;
}
}
else
{
while (count)
{
tputs(insert_character, 1, outc);
PutChar(*line);
line++;
count--;
}
}
}
X/*
** DelChar(count)
**
** Delete count characters at current position
**
*/
DelChar(count)
int count;
{
#ifdef TRACE
if (_tracing)
_tracef("DelChar(%d) called", count);
#endif
if (parm_dch)
{
tputs(tparm(parm_dch, count), 1, outc);
}
else
{
while (count--)
tputs(delete_character, 1, outc);
}
}
X/*
** InsLine(lineno, lastLine)
**
** Insert line number lineno, affecting up to lastLine
**
*/
InsLine(lineno, lastLine)
int lineno, lastLine;
{
int i, j, k;
chtype *temp;
chtype *line = newscr->_line[lineno];
#ifdef TRACE
if (_tracing)
_tracef("InsLine(%d,%d) called", lineno, lastLine);
#endif
GoTo(lineno, 0);
tputs(insert_line, 1, outc);
for (i=0; i < columns; i++)
PutChar(line[i]);
temp = curscr->_line[lastLine];
for (k = lastLine; k > lineno; k--)
curscr->_line[k] = curscr->_line[k - 1];
curscr->_line[k] = temp;
for (j=0; j < columns; j++)
curscr->_line[k][j] = newscr->_line[k][j];
}
X/*
** DelLine(count, lineno, lastLine)
**
** Delete count lines at lineno, affecting up to lastLine
**
*/
DelLine(count, lineno, lastLine)
int count, lineno, lastLine;
{
int j, k;
chtype *temp;
#ifdef TRACE
if (_tracing)
_tracef("DelLine(%d,%d,%d) called", count, lineno, lastLine);
#endif
GoTo(lineno, 0);
if (parm_delete_line)
{
tputs(tparm(parm_delete_line, count), 1, outc);
}
else
{
while (count--)
tputs(delete_line, 1, outc);
}
for (k = lineno; k + count <= lastLine; k++)
{
temp = curscr->_line[k];
curscr->_line[k] = curscr->_line[k + count];
curscr->_line[k + count] = temp;
}
for (; k <= lastLine; k++)
for (j=0; j < columns; j++)
curscr->_line[k][j] = ' ';
}
//go.sysin dd *
echo 'x - =src/lib_overlay.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_overlay.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_overlay.c
**
** The routines overlay() and overwrite().
**
** $Log: RCS/lib_overlay.v $
* Revision 2.2 82/10/28 18:10:11 pavel
* Fixed confusion about which direction the copy was supposed to go and
* also added updates to win2->_{first,last}char.
*
* Revision 2.1 82/10/25 14:48:35 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:48:09 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_overlay.v Revision 2.2 82/10/28 18:10:11 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
X/*
**
** overlay(win1, win2)
**
**
** overlay() writes win1 on win2 non-destructively.
**
**/
overlay(win1, win2)
WINDOW *win1, *win2;
{
int col, line, last_line, last_col;
short *firstchar, *lastchar;
chtype *w1ptr, *w2ptr, attrs;
#ifdef TRACE
if (_tracing)
_tracef("overlay(%o, %o) called", win1, win2);
#endif
last_col = min(win1->_maxx, win2->_maxx);
last_line = min(win1->_maxy, win2->_maxy);
attrs = win2->_attrs;
firstchar = win2->_firstchar;
lastchar = win2->_lastchar;
for(line = 0; line <= last_line; line++)
{
short fc, lc;
w1ptr = win1->_line[line];
w2ptr = win2->_line[line];
fc = _NOCHANGE;
for(col = 0; col <= last_col; col++)
{
if ((*w1ptr & A_CHARTEXT) != ' ')
{
*w2ptr = (*w1ptr & A_CHARTEXT) | attrs;
if (fc == _NOCHANGE)
fc = col;
lc = col;
}
w1ptr++;
w2ptr++;
}
if (*firstchar == _NOCHANGE)
{
*firstchar = fc;
*lastchar = lc;
}
else if (fc != _NOCHANGE)
{
if (fc < *firstchar)
*firstchar = fc;
if (lc > *lastchar)
*lastchar = lc;
}
firstchar++;
lastchar++;
}
}
X/*
**
** overwrite(win1, win2)
**
**
** overwrite() writes win1 on win2 destructively.
**
**/
overwrite(win1, win2)
WINDOW *win1, *win2;
{
int col, line, last_line, last_col;
short *firstchar, *lastchar;
chtype *w1ptr, *w2ptr, attrs;
#ifdef TRACE
if (_tracing)
_tracef("overwrite(%o, %o) called", win1, win2);
#endif
last_col = min(win1->_maxx, win2->_maxx);
last_line = min(win1->_maxy, win2->_maxy);
attrs = win2->_attrs;
firstchar = win2->_firstchar;
lastchar = win2->_lastchar;
for(line = 0; line <= last_line; line++)
{
short fc, lc;
w1ptr = win1->_line[line];
w2ptr = win2->_line[line];
fc = _NOCHANGE;
for(col = 0; col <= last_col; col++)
{
if ((*w1ptr & A_CHARTEXT) != (*w2ptr & A_CHARTEXT))
{
*w2ptr = (*w1ptr & A_CHARTEXT) | attrs;
if (fc == _NOCHANGE)
fc = col;
lc = col;
}
w1ptr++;
w2ptr++;
}
if (*firstchar == _NOCHANGE)
{
*firstchar = fc;
*lastchar = lc;
}
else if (fc != _NOCHANGE)
{
if (fc < *firstchar)
*firstchar = fc;
if (lc > *lastchar)
*lastchar = lc;
}
firstchar++;
lastchar++;
}
}
//go.sysin dd *
echo 'x - =src/lib_printw.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_printw.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_printw.c
**
** The routines printw(), wprintw() and friend.
**
** $Log: RCS/lib_printw.v $
* Revision 2.1 82/10/25 14:48:38 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:48:22 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_printw.v Revision 2.1 82/10/25 14:48:38 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
printw(fmt, args)
char *fmt;
int args;
{
#ifdef TRACE
if (_tracing)
_tracef("printw(%s,...) called", fmt);
#endif
return(sprintw(stdscr, fmt, &args));
}
wprintw(win, fmt, args)
WINDOW *win;
char *fmt;
int args;
{
#ifdef TRACE
if (_tracing)
_tracef("wprintw(%o,%s,...) called", win, fmt);
#endif
return(sprintw(win, fmt, &args));
}
mvprintw(y, x, fmt, args)
int y, x;
char *fmt;
int args;
{
return(move(y, x) == OK ? sprintw(stdscr, fmt, &args) : ERR);
}
mvwprintw(win, y, x, fmt, args)
WINDOW *win;
int y, x;
char *fmt;
int args;
{
return(wmove(win, y, x) == OK ? sprintw(win, fmt, &args) : ERR);
}
X/*
** This routine actually executes the printf and adds it to the window
**
** This is really a modified version of "sprintf". As such,
** it assumes that sprintf interfaces with the other printf functions
** in a certain way. If this is not how your system works, you
** will have to modify this routine to use the interface that your
** "sprintf" uses.
*/
static
sprintw(win, fmt, args)
WINDOW *win;
char *fmt;
int *args;
{
FILE junk;
char buf[512];
junk._flag = _IOWRT + _IOSTRG;
junk._ptr = buf;
junk._cnt = 32767;
_doprnt(fmt, args, &junk);
putc('\0', &junk);
return(waddstr(win, buf));
}
//go.sysin dd *
echo 'x - =src/lib_raw.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_raw.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/*
* raw.c
*
* Routines:
* raw()
* echo()
* nl()
* cbreak()
* crmode()
* noraw()
* noecho()
* nonl()
* nocbreak()
* nocrmode()
*
* cbreak() == crmode()
* nocbreak() == crmode()
*
* $Log: RCS/lib_raw.v $
* Revision 2.1 82/10/25 14:48:42 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/24 15:17:40 pavel
* Beta-one Test Release
*
* Revision 1.3 82/08/23 22:30:32 pavel
* The REAL Alpha-one Release Version
*
* Revision 1.2 82/08/19 19:11:25 pavel
* Alpha Test Release One
*
* Revision 1.1 82/08/12 18:43:18 pavel
* Initial revision
*
*
*/
static char RCSid[] =
"$Header: RCS/lib_raw.v Revision 2.1 82/10/25 14:48:42 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
#include "term.h"
raw()
{
#ifdef UNDEFINED
if (_tracing)
_tracef("raw() called");
#endif
cur_term->Nttyb.sg_flags |= RAW;
stty(cur_term->Filedes, &cur_term->Nttyb);
SP->_raw = TRUE;
SP->_nlmapping = TRUE;
}
cbreak()
{
#ifdef UNDEFINED
if (_tracing)
_tracef("cbreak() called");
#endif
cur_term->Nttyb.sg_flags |= CBREAK;
stty(cur_term->Filedes, &cur_term->Nttyb);
SP->_cbreak = TRUE;
}
crmode()
{
#ifdef UNDEFINED
if (_tracing)
_tracef("crmode() called");
#endif
cbreak();
}
echo()
{
#ifdef UNDEFINED
if (_tracing)
_tracef("echo() called");
#endif
cur_term->Nttyb.sg_flags |= ECHO;
stty(cur_term->Filedes, &cur_term->Nttyb);
SP->_echo = TRUE;
}
nl()
{
#ifdef UNDEFINED
if (_tracing)
_tracef("nl() called");
#endif
cur_term->Nttyb.sg_flags |= CRMOD;
stty(cur_term->Filedes, &cur_term->Nttyb);
SP->_nl = TRUE;
SP->_nlmapping = ! SP->_raw;
}
noraw()
{
#ifdef UNDEFINED
if (_tracing)
_tracef("noraw() called");
#endif
cur_term->Nttyb.sg_flags &= ~RAW;
stty(cur_term->Filedes, &cur_term->Nttyb);
SP->_raw = FALSE;
SP->_nlmapping = SP->_nl;
}
nocbreak()
{
#ifdef UNDEFINED
if (_tracing)
_tracef("nocbreak() called");
#endif
cur_term->Nttyb.sg_flags &= ~CBREAK;
stty(cur_term->Filedes, &cur_term->Nttyb);
SP->_cbreak = FALSE;
}
nocrmode()
{
#ifdef UNDEFINED
if (_tracing)
_tracef("nocrmode() called");
#endif
nocbreak();
}
noecho()
{
#ifdef UNDEFINED
if (_tracing)
_tracef("noecho() called");
#endif
cur_term->Nttyb.sg_flags &= ~ECHO;
stty(cur_term->Filedes, &cur_term->Nttyb);
SP->_echo = FALSE;
}
nonl()
{
#ifdef UNDEFINED
if (_tracing)
_tracef("nonl() called");
#endif
cur_term->Nttyb.sg_flags &= ~CRMOD;
stty(cur_term->Filedes, &cur_term->Nttyb);
SP->_nl = FALSE;
SP->_nlmapping = FALSE;
}
//go.sysin dd *
echo 'x - =src/lib_refresh.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_refresh.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_refresh.c
*
* The routines wrefresh() and wnoutrefresh().
*
* $Log: lib_refresh.c,v $
* Revision 3.1 84/12/13 11:20:51 john
* Revisions by Mark Horton
*
* Revision 2.1 82/10/25 14:48:45 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:48:47 pavel
* Beta-one Test Release
*
*
*/
static char RCSid[] =
"$Header: lib_refresh.c,v 3.1 84/12/13 11:20:51 john Exp $";
#include "curses.h"
#include "curses.priv.h"
wrefresh(win)
WINDOW *win;
{
#ifdef TRACE
if (_tracing)
_tracef("wrefresh(%o) called", win);
#endif
if (win == curscr)
{
curscr->_clear = TRUE;
doupdate();
}
else
{
wnoutrefresh(win);
doupdate();
}
}
wnoutrefresh(win)
WINDOW *win;
{
int i, j;
int begx = win->_begx;
int begy = win->_begy;
int m, n;
#ifdef TRACE
if (_tracing)
_tracef("wnoutrefresh(%o) called", win);
#endif
for (i=0, m=begy; i <= win->_maxy; i++, m++)
{
#ifdef TRACE
if (_tracing)
{
_tracef("win->_firstchar[%d]= %d\t_lastchar= %d\t_numchngd= %d",
i, win->_firstchar[i],
win->_lastchar[i],
win->_numchngd[i]);
}
#endif
if (win->_numchngd[i])
{
j = win->_firstchar[i];
n = j + begx;
for (; j <= win->_lastchar[i]; j++, n++)
{
if (win->_line[i][j] != newscr->_line[m][n])
{
newscr->_line[m][n] = win->_line[i][j];
newscr->_numchngd[m] += 1;
if (newscr->_firstchar[m] == _NOCHANGE)
newscr->_firstchar[m] = newscr->_lastchar[m] = n;
else if (n < newscr->_firstchar[m])
newscr->_firstchar[m] = n;
else if (n > newscr->_lastchar[m])
newscr->_lastchar[m] = n;
}
}
}
win->_numchngd[i] = 0;
win->_firstchar[i] = win->_lastchar[i] = _NOCHANGE;
}
if (win->_clear)
{
win->_clear = FALSE;
newscr->_clear = TRUE;
}
if (! win->_leave)
{
newscr->_cury = win->_cury + win->_begy;
newscr->_curx = win->_curx + win->_begx;
}
}
//go.sysin dd *
echo 'x - =src/lib_scanw.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_scanw.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_scanw.c
**
** The routines scanw(), wscanw() and friend.
**
** $Log: RCS/lib_scanw.v $
* Revision 2.1 82/10/25 14:48:51 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:49:07 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_scanw.v Revision 2.1 82/10/25 14:48:51 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
scanw(fmt, args)
char *fmt;
int args;
{
#ifdef TRACE
if (_tracing)
_tracef("scanw(%s,...) called", fmt);
#endif
return(sscans(stdscr, fmt, &args));
}
wscanw(win, fmt, args)
WINDOW *win;
char *fmt;
int args;
{
#ifdef TRACE
if (_tracing)
_tracef("wscanw(%o,%s,...) called", win, fmt);
#endif
return(sscans(win, fmt, &args));
}
mvscanw(y, x, fmt, args)
int y, x;
char *fmt;
int args;
{
return(move(y, x) == OK ? sscanw(stdscr, fmt, &args) : ERR);
}
mvwscanw(win, y, x, fmt, args)
WINDOW *win;
int y, x;
char *fmt;
int args;
{
return(wmove(win, y, x) == OK ? sscanw(win, fmt, &args) : ERR);
}
X/*
** This routine actually executes the scanf from the window.
**
** This is really a modified version of "sscanf". As such,
** it assumes that sscanf interfaces with the other scanf functions
** in a certain way. If this is not how your system works, you
** will have to modify this routine to use the interface that your
** "sscanf" uses.
*/
static
sscans(win, fmt, args)
WINDOW *win;
char *fmt;
int *args;
{
char buf[100];
FILE junk;
junk._flag = _IOREAD|_IOSTRG;
junk._base = junk._ptr = buf;
if (wgetstr(win, buf) == ERR)
return(ERR);
junk._cnt = strlen(buf);
return(_doscan(&junk, fmt, args));
}
//go.sysin dd *
echo 'x - =src/lib_scroll.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_scroll.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_scroll.c
**
** The routine scroll().
**
** $Log: RCS/lib_scroll.v $
* Revision 2.1 82/10/25 14:48:54 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:49:22 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_scroll.v Revision 2.1 82/10/25 14:48:54 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
scroll(win)
WINDOW *win;
{
int i;
chtype *ptr, *temp;
chtype blank = ' ' | win->_attrs;
#ifdef TRACE
if (_tracing)
_tracef("scroll(%o) called", win);
#endif
if (! win->_scroll)
return;
temp = win->_line[0];
for (i = 0; i < win->_regbottom; i++)
win->_line[i] = win->_line[i+1];
for (ptr = temp; ptr - temp <= win->_maxx; ptr++)
*ptr = blank;
win->_line[win->_regbottom] = temp;
win->_cury--;
}
//go.sysin dd *
echo 'x - =src/lib_scrreg.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_scrreg.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_scrreg.c
**
** The routine wsetscrreg().
**
** $Log: RCS/lib_scrreg.v $
* Revision 2.1 82/10/25 14:49:00 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:49:29 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_scrreg.v Revision 2.1 82/10/25 14:49:00 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
wsetscrreg(win, top, bottom)
WINDOW *win;
int top, bottom;
{
#ifdef TRACE
if (_tracing)
_tracef("wsetscrreg(%o,%d,%d) called", win, top, bottom);
#endif
if (0 <= top && top <= win->_cury &&
win->_cury <= bottom && bottom <= win->_maxy)
{
win->_regtop = top;
win->_regbottom = bottom;
return(OK);
}
else
return(ERR);
}
//go.sysin dd *
echo 'x - =src/lib_set_term.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_set_term.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_set_term.c
**
** The routine set_term().
**
** $Log: RCS/lib_set_term.v $
* Revision 2.1 82/10/25 14:49:06 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:49:42 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_set_term.v Revision 2.1 82/10/25 14:49:06 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
#include "term.h"
struct screen *
set_term(screen)
struct screen *screen;
{
struct screen *oldSP;
#ifdef TRACE
if (_tracing)
_tracef("set_term(%o) called", screen);
#endif
oldSP = SP;
SP = screen;
cur_term = SP->_term;
curscr = SP->_curscr;
newscr = SP->_newscr;
return(oldSP);
}
//go.sysin dd *
echo 'x - =src/lib_setup.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_setup.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/*
* setupterm(termname, filedes, errret)
*
* Find and read the appropriate object file for the terminal
* Make cur_term point to the structure.
* Turn off the XTABS bit in the tty structure if it was on
* If XTABS was on, remove the tab and backtab capabilities.
*
* $Log: RCS/lib_setup.v $
* Revision 2.1 82/10/25 14:49:09 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/24 15:17:46 pavel
* Beta-one Test Release
*
* Revision 1.5 82/08/23 22:30:35 pavel
* The REAL Alpha-one Release Version
*
* Revision 1.4 82/08/20 15:12:24 pavel
* Fixed use of un-initialised cur_term.
*
* Revision 1.3 82/08/19 19:22:09 pavel
* Alpha Test Release One
*
* Revision 1.2 82/08/19 19:11:28 pavel
* Alpha Test Release One
*
* Revision 1.1 82/08/12 18:45:07 pavel
* Initial revision
*
*
*/
static char RCSid[] =
"$Header: RCS/lib_setup.v Revision 2.1 82/10/25 14:49:09 pavel Exp$";
#include <stdio.h>
#include "curses.h"
#include "curses.priv.h"
#include "term.h"
#define ret_error(code, fmt, arg) if (errret)\
{\
*errret = code;\
return(code);\
}\
else\
{\
fprintf(stderr, fmt, arg);\
exit(1);\
}
setupterm(termname, filedes, errret)
char *termname;
int filedes;
int *errret;
{
char filename1[1024];
char filename2[1024];
char *directory = SRCDIR;
char *malloc(), *getenv();
char *terminfo;
struct term *term_ptr;
#ifdef TRACE
_init_trace();
if (_tracing)
_tracef("setupterm(%s,%d,%o) called", termname, filedes, errret);
#endif
if (termname == NULL)
{
termname = getenv("TERM");
if (termname == NULL)
ret_error(-1, "TERM environment variable not set.\n", "");
}
if (cur_term == 0)
term_ptr = &_first_term;
else
{
term_ptr = (struct term *) malloc(sizeof(struct term));
if (term_ptr == NULL)
ret_error(-1, "Not enough memory to create terminal structure.\n", "");
}
if ((terminfo = getenv("TERMINFO")) != NULL)
directory = terminfo;
sprintf(filename1, "%s/%c/%s", directory, termname[0], termname);
sprintf(filename2, "%s/%c/%s", SRCDIR, termname[0], termname);
if (read_entry(filename1, term_ptr) < 0
&& read_entry(filename2, term_ptr) < 0)
ret_error(0, "'%s': Unknown terminal type.\n", termname);
if (command_character && getenv("CC"))
do_prototype();
cur_term = term_ptr;
strncpy(ttytype, cur_term->term_names, NAMESIZE - 1);
ttytype[NAMESIZE - 1] = '\0';
cur_term->Filedes = filedes;
gtty(filedes, &cur_term->Ottyb);
if (cur_term->Ottyb.sg_flags & XTABS)
tab = back_tab = NULL;
cur_term->Nttyb = cur_term->Ottyb;
cur_term->Nttyb.sg_flags &= ~XTABS;
fixterm();
if (errret)
*errret = 1;
return(1);
}
X/*
** do_prototype()
**
** Take the real command character out of the CC environment variable
** and substitute it in for the prototype given in 'command_character'.
**
*/
static
do_prototype()
{
int i, j;
char CC;
char proto;
CC = *getenv("CC");
proto = *command_character;
for (i=0; i < STRCOUNT; i++)
{
j = 0;
while (cur_term->Strings[i][j])
{
if (cur_term->Strings[i][j] == proto)
cur_term->Strings[i][j] = CC;
j++;
}
}
}
//go.sysin dd *
echo 'x - =src/lib_touchwin.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_touchwin.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_touchwin.c
**
** The routine touchwin().
**
** $Log: RCS/lib_touchwin.v $
* Revision 2.1 82/10/25 14:49:13 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/25 13:49:52 pavel
* Beta-one Test Release
*
**
*/
static char RCSid[] =
"$Header: RCS/lib_touchwin.v Revision 2.1 82/10/25 14:49:13 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
touchwin(win)
WINDOW *win;
{
int y, maxy, maxx;
#ifdef TRACE
if (_tracing)
_tracef("touchwin(%o) called", win);
#endif
maxy = win->_maxy;
maxx = win->_maxx;
for (y = 0; y <= maxy; y++)
{
win->_firstchar[y] = 0;
win->_lastchar[y] = maxx;
win->_numchngd[y] = maxx;
}
}
//go.sysin dd *
echo 'x - =src/lib_tparm.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_tparm.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/*
* tparm.c
*
* $Log: RCS/lib_tparm.v $
* Revision 2.1 82/10/25 14:49:19 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/24 15:17:53 pavel
* Beta-one Test Release
*
* Revision 1.3 82/08/23 22:30:38 pavel
* The REAL Alpha-one Release Version
*
* Revision 1.2 82/08/19 19:11:33 pavel
* Alpha Test Release One
*
* Revision 1.1 82/08/12 18:45:33 pavel
* Initial revision
*
*
*/
static char RCSid[] =
"$Header: RCS/lib_tparm.v Revision 2.1 82/10/25 14:49:19 pavel Exp$";
#include "curses.h"
#include "curses.priv.h"
#include "term.h"
X/*
* char *
* tparm(string, parms)
*
* Substitute the given parameters into the given string by the following
* rules (taken from terminfo(5)):
*
* Cursor addressing and other strings requiring parame-
* ters in the terminal are described by a parameterized string
* capability, with like escapes %x in it. For example, to
* address the cursor, the cup capability is given, using two
* parameters: the row and column to address to. (Rows and
* columns are numbered from zero and refer to the physical
* screen visible to the user, not to any unseen memory.) If
* the terminal has memory relative cursor addressing, that can
* be indicated by
*
* The parameter mechanism uses a stack and special %
* codes to manipulate it. Typically a sequence will push one
* of the parameters onto the stack and then print it in some
* format. Often more complex operations are necessary.
*
* The % encodings have the following meanings:
*
* %% outputs `%'
* %d print pop() like %d in printf()
* %2d print pop() like %2d in printf()
* %02d print pop() like %02d in printf()
* %3d print pop() like %3d in printf()
* %03d print pop() like %03d in printf()
* %c print pop() like %c in printf()
* %s print pop() like %s in printf()
*
* %p[1-9] push ith parm
* %P[a-z] set variable [a-z] to pop()
* %g[a-z] get variable [a-z] and push it
* %'c' push char constant c
* %{nn} push integer constant nn
*
* %+ %- %* %/ %m
* arithmetic (%m is mod): push(pop() op pop())
* %& %| %^ bit operations: push(pop() op pop())
* %= %> %< logical operations: push(pop() op pop())
* %! %~ unary operations push(op pop())
* %i add 1 to first two parms (for ANSI terminals)
*
* %? expr %t thenpart %e elsepart %;
* if-then-else, %e elsepart is optional.
* else-if's are possible ala Algol 68:
* %? c1 %t b1 %e c2 %t b2 %e c3 %t b3 %e c4 %t b4 %e b5 %;
*
* For those of the above operators which are binary and not commutative,
* the stack works in the usual way, with
* %gx %gy %m
* resulting in x mod y, not the reverse.
*/
#define STACKSIZE 20
#define npush(x) if (stack_ptr < STACKSIZE) {stack[stack_ptr].num = x;\
stack_ptr++;\
}
#define npop() (stack_ptr > 0 ? stack[--stack_ptr].num : 0)
#define spop() (stack_ptr > 0 ? stack[--stack_ptr].str : (char *) 0)
typedef union
{
unsigned int num;
char *str;
} stack_frame;
stack_frame stack[STACKSIZE];
static int stack_ptr;
static char buffer[256];
static int *param;
static char *bufptr;
static int variable[26];
static char *do_tparm();
char *
tparm(string, parms)
char *string;
int parms;
{
char len;
int number;
int level;
int x, y;
param = &parms;
#ifdef UNDEFINED
if (_tracing)
_tracef("tparm(%s,%d,%d,%d,%d,%d,%d,%d,%d,%d) called",
string, param[0], param[1], param[2], param[3],
param[4], param[5], param[6], param[7], param[8]);
#endif
stack_ptr = 0;
bufptr = buffer;
while (*string)
{
if (*string != '%')
*(bufptr++) = *string;
else
{
string++;
switch (*string)
{
default:
break;
case '%':
*(bufptr++) = '%';
break;
case 'd':
sprintf(bufptr, "%d", npop());
bufptr += strlen(bufptr);
break;
case '0':
string++;
len = *string;
if ((len == '2' || len == '3') && *++string == 'd')
{
if (len == '2')
sprintf(bufptr, "%02d", npop());
else
sprintf(bufptr, "%03d", npop());
bufptr += strlen(bufptr);
}
break;
case '2':
string++;
if (*string == 'd')
{
sprintf(bufptr, "%2d", npop());
bufptr += strlen(bufptr);
}
break;
case '3':
string++;
if (*string == 'd')
{
sprintf(bufptr, "%3d", npop());
bufptr += strlen(bufptr);
}
break;
case 'c':
*(bufptr++) = (char) npop();
break;
case 's':
strcpy(bufptr, spop());
bufptr += strlen(bufptr);
break;
case 'p':
string++;
if (*string >= '1' && *string <= '9')
npush(param[*string - '1']);
break;
case 'P':
string++;
if (*string >= 'a' && *string <= 'z')
variable[*string - 'a'] = npop();
break;
case 'g':
string++;
if (*string >= 'a' && *string <= 'z')
npush(variable[*string - 'a']);
break;
case '\'':
string++;
npush(*string);
string++;
break;
case '{':
number = 0;
string++;
while (*string >= '0' && *string <= '9')
{
number = number * 10 + *string - '0';
string++;
}
npush(number);
break;
case '+':
npush(npop() + npop());
break;
case '-':
y = npop();
x = npop();
npush(x - y);
break;
case '*':
npush(npop() * npop());
break;
case '/':
y = npop();
x = npop();
npush(x / y);
break;
case 'm':
y = npop();
x = npop();
npush(x % y);
break;
case '&':
npush(npop() & npop());
break;
case '|':
npush(npop() | npop());
break;
case '^':
npush(npop() ^ npop());
break;
case '=':
y = npop();
x = npop();
npush(x == y);
break;
case '<':
y = npop();
x = npop();
npush(x < y);
break;
case '>':
y = npop();
x = npop();
npush(x > y);
break;
case '!':
npush(! npop());
break;
case '~':
npush(~ npop());
break;
case 'i':
param[0]++;
param[1]++;
break;
case '?':
break;
case 't':
x = npop();
if (x)
{
/* do nothing; keep executing */
}
else
{
/* scan forward for %e or %; at level zero */
string++;
level = 0;
while (*string)
{
if (*string == '%')
{
string++;
if (*string == '?')
level++;
else if (*string == ';')
{
if (level > 0)
level--;
else
break;
}
else if (*string == 'e' && level == 0)
break;
}
if (*string)
string++;
}
}
break;
case 'e':
/* scan forward for a %; at level zero */
string++;
level = 0;
while (*string)
{
if (*string == '%')
{
string++;
if (*string == '?')
level++;
else if (*string == ';')
{
if (level > 0)
level--;
else
break;
}
}
if (*string)
string++;
}
break;
case ';':
break;
} /* endswitch (*string) */
} /* endelse (*string == '%') */
if (*string == '\0')
break;
string++;
} /* endwhile (*string) */
*bufptr = '\0';
return(buffer);
}
X/*
* char *
* tgoto(string, x, y)
*
* Retained solely for upward compatibility. Note the intentional
* reversing of the last two arguments.
*
*/
char *
tgoto(string, x, y)
char *string;
int x, y;
{
return(tparm(string, y, x));
}
//go.sysin dd *
exit
More information about the Mod.sources
mailing list