Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/3/84; site genrad.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!genrad!sources From: sources@genrad.UUCP Newsgroups: mod.sources Subject: PD Terminfo/Curses (part 8 of 11) Message-ID: <540@genrad.UUCP> Date: Thu, 20-Dec-84 07:29:11 EST Article-I.D.: genrad.540 Posted: Thu Dec 20 07:29:11 1984 Date-Received: Fri, 21-Dec-84 02:16:00 EST Sender: john@genrad.UUCP Organization: GenRad, Inc., Bolton, Mass. Lines: 2545 Approved: john@genrad.UUCP 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@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#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@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@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@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@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@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@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@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@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@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 #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@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@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