xref: /csrg-svn/games/rogue/curses.c (revision 60842)
132689Sbostic /*
2*60842Sbostic  * Copyright (c) 1988, 1993
3*60842Sbostic  *	The Regents of the University of California.  All rights reserved.
436704Sbostic  *
536704Sbostic  * This code is derived from software contributed to Berkeley by
636704Sbostic  * Timothy C. Stoehr.
736704Sbostic  *
842591Sbostic  * %sccs.include.redist.c%
936704Sbostic  */
1036704Sbostic 
1136704Sbostic #ifndef lint
12*60842Sbostic static char sccsid[] = "@(#)curses.c	8.1 (Berkeley) 05/31/93";
1336704Sbostic #endif /* not lint */
1436704Sbostic 
1536704Sbostic /*
1632689Sbostic  * curses.c
1732689Sbostic  *
1832689Sbostic  * This source herein may be modified and/or distributed by anybody who
1932689Sbostic  * so desires, with the following restrictions:
2032689Sbostic  *    1.)  No portion of this notice shall be removed.
2132689Sbostic  *    2.)  Credit shall not be taken for the creation of this source.
2232689Sbostic  *    3.)  This code is not to be traded, sold, or used for personal
2332689Sbostic  *         gain or profit.
2432689Sbostic  *
2532689Sbostic  */
2632689Sbostic 
2732689Sbostic #ifdef CURSES
2832689Sbostic 
2932689Sbostic /* The following is a curses emulation package suitable for the rogue program
3032689Sbostic  * in which it is included.  No other suitability is claimed or suspected.
3132689Sbostic  * Only those routines currently needed by this rogue program are included.
3232689Sbostic  * This is being provided for those systems that don't have a suitable
3332689Sbostic  * curses package and want to run this rogue program.
3432689Sbostic  *
3532689Sbostic  * Compile the entire program with -DCURSES to incorporate this package.
3632689Sbostic  *
3732689Sbostic  * The following is NOT supported:
3832689Sbostic  *   "%D", "%B", "%n", or "%>" inside a cursor motion (cm) termcap string.
3932689Sbostic  *   Terminals in which the cursor motion addresses the row differently from
4032689Sbostic  *       the column, as in ":cm=\E%2,%3" or ":cm=\EY%+x;%+y"
4132689Sbostic  *   Termcap database stored in the TERMCAP environ variable as returned
4232689Sbostic  *       from md_getenv().  Only the termcap file name can be stored there.
4332689Sbostic  *       See the comments for md_getenv() in machdep.c.
4432689Sbostic  *   Terminals without non-destructive backspace.  Backspace (^H) is used
4532689Sbostic  *       for cursor motion regardless of any termcap entries.
4632689Sbostic  *   The ":tc=" termcap entry is ignored.
4732689Sbostic  *
4832689Sbostic  * Suggestions:
4932689Sbostic  *   Use line-feed as your termcap "do" entry: ":do=^J", ":do=\012" or
5032689Sbostic  *      ":do=\n"  This will help cursor motion optimization.  If line-feed
5132689Sbostic  *      won't work, then a short escape sequence will do.
5232689Sbostic  */
5332689Sbostic 
5432689Sbostic #include <stdio.h>
5532689Sbostic #include "rogue.h"
5632689Sbostic 
5732689Sbostic boolean tc_tname();
5832689Sbostic 
5932689Sbostic #define BS 010
6032689Sbostic #define LF 012
6132689Sbostic #define CR 015
6232689Sbostic #define ESC '\033'
6332689Sbostic #define TAB '\011'
6432689Sbostic 
6532689Sbostic #define ST_MASK 0x80
6632689Sbostic #define BUFLEN 256
6732689Sbostic 
6832689Sbostic char terminal[DROWS][DCOLS];
6932689Sbostic char buffer[DROWS][DCOLS];
7032689Sbostic char *tc_file;
7132689Sbostic 
7232689Sbostic char cm_esc[16];
7332689Sbostic char cm_sep[16];
7432689Sbostic char cm_end[16];
7532689Sbostic boolean cm_reverse = 0;
7632689Sbostic boolean cm_two = 0;
7732689Sbostic boolean cm_three = 0;
7832689Sbostic boolean cm_char = 0;
7932689Sbostic short cm_inc = 0;
8032689Sbostic 
8132689Sbostic boolean screen_dirty;
8232689Sbostic boolean lines_dirty[DROWS];
8332689Sbostic boolean buf_stand_out = 0;
8432689Sbostic boolean term_stand_out = 0;
8532689Sbostic 
8632689Sbostic int LINES = DROWS;
8732689Sbostic int COLS = DCOLS;
8832689Sbostic WINDOW scr_buf;
8932689Sbostic WINDOW *curscr = &scr_buf;
9032689Sbostic 
9132689Sbostic char *CL = (char *) 0;
9232689Sbostic char *CM = (char *) 0;
9332689Sbostic char *UC = (char *) 0;	/* UP */
9432689Sbostic char *DO = (char *) 0;
9532689Sbostic char *VS = "";
9632689Sbostic char *VE = "";
9732689Sbostic char *TI = "";
9832689Sbostic char *TE = "";
9932689Sbostic char *SO = "";
10032689Sbostic char *SE = "";
10132689Sbostic 
10232689Sbostic short cur_row;
10332689Sbostic short cur_col;
10432689Sbostic 
initscr()10532689Sbostic initscr()
10632689Sbostic {
10732689Sbostic 	clear();
10832689Sbostic 	get_term_info();
10932689Sbostic 	printf("%s%s", TI, VS);
11032689Sbostic }
11132689Sbostic 
endwin()11232689Sbostic endwin()
11332689Sbostic {
11432689Sbostic 	printf("%s%s", TE, VE);
11532689Sbostic 	md_cbreak_no_echo_nonl(0);
11632689Sbostic }
11732689Sbostic 
move(row,col)11832689Sbostic move(row, col)
11932689Sbostic short row, col;
12032689Sbostic {
12132689Sbostic 	curscr->_cury = row;
12232689Sbostic 	curscr->_curx = col;
12332689Sbostic 	screen_dirty = 1;
12432689Sbostic }
12532689Sbostic 
mvaddstr(row,col,str)12632689Sbostic mvaddstr(row, col, str)
12732689Sbostic short row, col;
12832689Sbostic char *str;
12932689Sbostic {
13032689Sbostic 	move(row, col);
13132689Sbostic 	addstr(str);
13232689Sbostic }
13332689Sbostic 
addstr(str)13432689Sbostic addstr(str)
13532689Sbostic char *str;
13632689Sbostic {
13732689Sbostic 	while (*str) {
13832689Sbostic 		addch((int) *str++);
13932689Sbostic 	}
14032689Sbostic }
14132689Sbostic 
addch(ch)14232689Sbostic addch(ch)
14332689Sbostic register int ch;
14432689Sbostic {
14532689Sbostic 	short row, col;
14632689Sbostic 
14732689Sbostic 	row = curscr->_cury;
14832689Sbostic 	col = curscr->_curx++;
14932689Sbostic 
15032689Sbostic 	if (buf_stand_out) {
15132689Sbostic 		ch |= ST_MASK;
15232689Sbostic 	}
15332689Sbostic 	buffer[row][col] = (char) ch;
15432689Sbostic 	lines_dirty[row] = 1;
15532689Sbostic 	screen_dirty = 1;
15632689Sbostic }
15732689Sbostic 
mvaddch(row,col,ch)15832689Sbostic mvaddch(row, col, ch)
15932689Sbostic short row, col;
16032689Sbostic int ch;
16132689Sbostic {
16232689Sbostic 	move(row, col);
16332689Sbostic 	addch(ch);
16432689Sbostic }
16532689Sbostic 
refresh()16632689Sbostic refresh()
16732689Sbostic {
16832689Sbostic 	register i, j, line;
16932689Sbostic 	short old_row, old_col, first_row;
17032689Sbostic 
17132689Sbostic 	if (screen_dirty) {
17232689Sbostic 
17332689Sbostic 		old_row = curscr->_cury;
17432689Sbostic 		old_col = curscr->_curx;
17532689Sbostic 		first_row = cur_row;
17632689Sbostic 
17732689Sbostic 		for (i = 0; i < DROWS; i++) {
17832689Sbostic 			line = (first_row + i) % DROWS;
17932689Sbostic 			if (lines_dirty[line]) {
18032689Sbostic 				for (j = 0; j < DCOLS; j++) {
18132689Sbostic 					if (buffer[line][j] != terminal[line][j]) {
18232689Sbostic 						put_char_at(line, j, buffer[line][j]);
18332689Sbostic 					}
18432689Sbostic 				}
18532689Sbostic 				lines_dirty[line] = 0;
18632689Sbostic 			}
18732689Sbostic 		}
18832689Sbostic 		put_cursor(old_row, old_col);
18932689Sbostic 		screen_dirty = 0;
19032689Sbostic 		fflush(stdout);
19132689Sbostic 	}
19232689Sbostic }
19332689Sbostic 
wrefresh(scr)19432689Sbostic wrefresh(scr)
19532689Sbostic WINDOW *scr;
19632689Sbostic {
19732689Sbostic 	short i, col;
19832689Sbostic 
19932689Sbostic 	printf("%s", CL);
20032689Sbostic 	cur_row = cur_col = 0;
20132689Sbostic 
20232689Sbostic 	for (i = 0; i < DROWS; i++) {
20332689Sbostic 		col = 0;
20432689Sbostic 		while (col < DCOLS) {
20532689Sbostic 			while ((col < DCOLS) && (buffer[i][col] == ' ')) {
20632689Sbostic 				col++;
20732689Sbostic 			}
20832689Sbostic 			if (col < DCOLS) {
20932689Sbostic 				put_cursor(i, col);
21032689Sbostic 			}
21132689Sbostic 			while ((col < DCOLS) && (buffer[i][col] != ' ')) {
21232689Sbostic 				put_st_char((int) buffer[i][col]);
21332689Sbostic 				cur_col++;
21432689Sbostic 				col++;
21532689Sbostic 			}
21632689Sbostic 		}
21732689Sbostic 	}
21832689Sbostic 	put_cursor(curscr->_cury, curscr->_curx);
21932689Sbostic 	fflush(stdout);
22032689Sbostic 	scr = scr;		/* make lint happy */
22132689Sbostic }
22232689Sbostic 
mvinch(row,col)22332689Sbostic mvinch(row, col)
22432689Sbostic short row, col;
22532689Sbostic {
22632689Sbostic 	move(row, col);
22732689Sbostic 	return((int) buffer[row][col]);
22832689Sbostic }
22932689Sbostic 
clear()23032689Sbostic clear()
23132689Sbostic {
23232689Sbostic 	printf("%s", CL);
23332689Sbostic 	fflush(stdout);
23432689Sbostic 	cur_row = cur_col = 0;
23532689Sbostic 	move(0, 0);
23632689Sbostic 	clear_buffers();
23732689Sbostic }
23832689Sbostic 
clrtoeol()23932689Sbostic clrtoeol()
24032689Sbostic {
24132689Sbostic 	short row, col;
24232689Sbostic 
24332689Sbostic 	row = curscr->_cury;
24432689Sbostic 
24532689Sbostic 	for (col = curscr->_curx; col < DCOLS; col++) {
24632689Sbostic 		buffer[row][col] = ' ';
24732689Sbostic 	}
24832689Sbostic 	lines_dirty[row] = 1;
24932689Sbostic }
25032689Sbostic 
standout()25132689Sbostic standout()
25232689Sbostic {
25332689Sbostic 	buf_stand_out = 1;
25432689Sbostic }
25532689Sbostic 
standend()25632689Sbostic standend()
25732689Sbostic {
25832689Sbostic 	buf_stand_out = 0;
25932689Sbostic }
26032689Sbostic 
crmode()26132689Sbostic crmode()
26232689Sbostic {
26332689Sbostic 	md_cbreak_no_echo_nonl(1);
26432689Sbostic }
26532689Sbostic 
noecho()26632689Sbostic noecho()
26732689Sbostic {
26832689Sbostic 	/* crmode() takes care of this */
26932689Sbostic }
27032689Sbostic 
nonl()27132689Sbostic nonl()
27232689Sbostic {
27332689Sbostic 	/* crmode() takes care of this */
27432689Sbostic }
27532689Sbostic 
clear_buffers()27632689Sbostic clear_buffers()
27732689Sbostic {
27832689Sbostic 	register i, j;
27932689Sbostic 
28032689Sbostic 	screen_dirty = 0;
28132689Sbostic 
28232689Sbostic 	for (i = 0; i < DROWS; i++) {
28332689Sbostic 		lines_dirty[i] = 0;
28432689Sbostic 		for (j = 0; j < DCOLS; j++) {
28532689Sbostic 			terminal[i][j] = ' ';
28632689Sbostic 			buffer[i][j] = ' ';
28732689Sbostic 		}
28832689Sbostic 	}
28932689Sbostic }
29032689Sbostic 
put_char_at(row,col,ch)29132689Sbostic put_char_at(row, col, ch)
29232689Sbostic register row, col, ch;
29332689Sbostic {
29432689Sbostic 	put_cursor(row, col);
29532689Sbostic 	put_st_char(ch);
29632689Sbostic 	terminal[row][col] = (char) ch;
29732689Sbostic 	cur_col++;
29832689Sbostic }
29932689Sbostic 
put_cursor(row,col)30032689Sbostic put_cursor(row, col)
30132689Sbostic register row, col;
30232689Sbostic {
30332689Sbostic 	register i, rdif, cdif;
30432689Sbostic 	short ch, t;
30532689Sbostic 
30632689Sbostic 	rdif = (row > cur_row) ? row - cur_row : cur_row - row;
30732689Sbostic 	cdif = (col > cur_col) ? col - cur_col : cur_col - col;
30832689Sbostic 
30932689Sbostic 	if (((row > cur_row) && DO) || ((cur_row > row) && UC)) {
31032689Sbostic 		if ((rdif < 4) && (cdif < 4)) {
31132689Sbostic 			for (i = 0; i < rdif; i++) {
31232689Sbostic 				printf("%s", ((row < cur_row) ? UC : DO));
31332689Sbostic 			}
31432689Sbostic 			cur_row = row;
31532689Sbostic 			if (col == cur_col) {
31632689Sbostic 				return;
31732689Sbostic 			}
31832689Sbostic 		}
31932689Sbostic 	}
32032689Sbostic 	if (row == cur_row) {
32132689Sbostic 		if (cdif <= 6) {
32232689Sbostic 		for (i = 0; i < cdif; i++) {
32332689Sbostic 				ch = (col < cur_col) ? BS :
32432689Sbostic 						terminal[row][cur_col + i];
32532689Sbostic 				put_st_char((int) ch);
32632689Sbostic 			}
32732689Sbostic 			cur_row = row;
32832689Sbostic 			cur_col = col;
32932689Sbostic 			return;
33032689Sbostic 		}
33132689Sbostic 	}
33232689Sbostic 	cur_row = row;
33332689Sbostic 	cur_col = col;
33432689Sbostic 
33532689Sbostic 	row += cm_inc;
33632689Sbostic 	col += cm_inc;
33732689Sbostic 
33832689Sbostic 	if (cm_reverse) {
33932689Sbostic 		t = row;
34032689Sbostic 		row = col;
34132689Sbostic 		col = t;
34232689Sbostic 	}
34332689Sbostic 	if (cm_two) {
34432689Sbostic 		printf("%s%02d%s%02d%s", cm_esc, row, cm_sep, col, cm_end);
34532689Sbostic 	} else if (cm_three) {
34632689Sbostic 		printf("%s%03d%s%03d%s", cm_esc, row, cm_sep, col, cm_end);
34732689Sbostic 	} else if (cm_char) {
34832689Sbostic 		printf("%s%c%s%c%s", cm_esc, row, cm_sep, col, cm_end);
34932689Sbostic 	} else {
35032689Sbostic 		printf("%s%d%s%d%s", cm_esc, row, cm_sep, col, cm_end);
35132689Sbostic 	}
35232689Sbostic }
35332689Sbostic 
put_st_char(ch)35432689Sbostic put_st_char(ch)
35532689Sbostic register ch;
35632689Sbostic {
35732689Sbostic 	if ((ch & ST_MASK) && (!term_stand_out)) {
35832689Sbostic 		ch &= ~ST_MASK;
35932689Sbostic 		printf("%s%c", SO, ch);
36032689Sbostic 		term_stand_out = 1;
36132689Sbostic 	} else if ((!(ch & ST_MASK)) && term_stand_out) {
36232689Sbostic 		printf("%s%c", SE, ch);
36332689Sbostic 		term_stand_out = 0;
36432689Sbostic 	} else {
36532689Sbostic 		ch &= ~ST_MASK;
36632689Sbostic 		putchar(ch);
36732689Sbostic 	}
36832689Sbostic }
36932689Sbostic 
get_term_info()37032689Sbostic get_term_info()
37132689Sbostic {
37232689Sbostic 	FILE *fp;
37332689Sbostic 	char *term, *tcf;
37432689Sbostic 	char buf[BUFLEN];
37532689Sbostic 
37632689Sbostic 	if (tcf = md_getenv("TERMCAP")) {
37732689Sbostic 		if (strlen(tcf) > 40) {
37832689Sbostic 			clean_up("TERMCAP file name too long");
37932689Sbostic 		}
38032689Sbostic 		tc_file = tcf;
38132689Sbostic 	} else {
38232689Sbostic 		if (!(tc_file = md_gdtcf())) {
38332689Sbostic 			clean_up("I need a termcap file");
38432689Sbostic 		}
38532689Sbostic 	}
38632689Sbostic 
38732689Sbostic 	if (!(term = md_getenv("TERM"))) {
38832689Sbostic 		clean_up("Cannot find TERM variable in environ");
38932689Sbostic 	}
39032689Sbostic 	if ((fp = fopen(tc_file, "r")) == NULL) {
39132689Sbostic 		sprintf(buf, "Cannot open TERMCAP file: %s", tc_file);
39232689Sbostic 		clean_up(buf);
39332689Sbostic 	}
39432689Sbostic 
39532689Sbostic 	if (!tc_tname(fp, term, buf)) {
39632689Sbostic 		sprintf(buf, "Cannot find TERM type: %s in TERMCAP file: %s", term,
39732689Sbostic 			tc_file);
39832689Sbostic 		clean_up(buf);
39932689Sbostic 	}
40032689Sbostic 	tc_gtdata(fp, buf);
40132689Sbostic 	fclose(fp);
40232689Sbostic }
40332689Sbostic 
40432689Sbostic boolean
tc_tname(fp,term,buf)40532689Sbostic tc_tname(fp, term, buf)
40632689Sbostic FILE *fp;
40732689Sbostic char *term;
40832689Sbostic char *buf;
40932689Sbostic {
41032689Sbostic 	short i, j;
41132689Sbostic 	boolean found = 0;
41232689Sbostic 	char *fg;
41332689Sbostic 
41432689Sbostic 	while (!found) {
41532689Sbostic 		i = 0;
41632689Sbostic 		fg = fgets(buf, BUFLEN, fp);
41732689Sbostic 		if (fg != NULL) {
41832689Sbostic 			if (	(buf[0] != '#') && (buf[0] != ' ') && (buf[0] != TAB) &&
41932689Sbostic 					(buf[0] != CR) && (buf[0] != LF)) {
42032689Sbostic 				while (buf[i] && (!found)) {
42132689Sbostic 					j = 0;
42232689Sbostic 					while (buf[i] == term[j]) {
42332689Sbostic 						i++;
42432689Sbostic 						j++;
42532689Sbostic 					}
42632689Sbostic 					if ((!term[j]) && ((buf[i] == '|') || (buf[i] == ':'))) {
42732689Sbostic 						found = 1;
42832689Sbostic 					} else {
42932689Sbostic 						while (buf[i] && (buf[i] != '|') && (buf[i] != ':')) {
43032689Sbostic 							i++;
43132689Sbostic 						}
43232689Sbostic 						if (buf[i]) {
43332689Sbostic 							i++;
43432689Sbostic 						}
43532689Sbostic 					}
43632689Sbostic 				}
43732689Sbostic 			}
43832689Sbostic 		} else {
43932689Sbostic 			break;
44032689Sbostic 		}
44132689Sbostic 	}
44232689Sbostic 	return(found);
44332689Sbostic }
44432689Sbostic 
tc_gtdata(fp,buf)44532689Sbostic tc_gtdata(fp, buf)
44632689Sbostic FILE *fp;
44732689Sbostic char *buf;
44832689Sbostic {
44932689Sbostic 	short i;
45032689Sbostic 	boolean first = 1;
45132689Sbostic 
45232689Sbostic 	do {
45332689Sbostic 		if (!first) {
45432689Sbostic 			if ((buf[0] != TAB) && (buf[0] != ' ')) {
45532689Sbostic 				break;
45632689Sbostic 			}
45732689Sbostic 		}
45832689Sbostic 		first = 0;
45932689Sbostic 		i = 0;
46032689Sbostic 		while (buf[i]) {
46132689Sbostic 			while (buf[i] && (buf[i] != ':')) {
46232689Sbostic 				i++;
46332689Sbostic 			}
46432689Sbostic 			if (buf[i] == ':') {
46532689Sbostic 				if (!strncmp(buf + i, ":cl=", 4)) {
46632689Sbostic 					tc_gets(buf + i, &CL);
46732689Sbostic 				} else if (!strncmp(buf + i, ":cm=", 4)) {
46832689Sbostic 					tc_gets(buf + i, &CM);
46932689Sbostic 				} else if (!strncmp(buf + i, ":up=", 4)) {
47032689Sbostic 					tc_gets(buf + i, &UC);
47132689Sbostic 				} else if (!strncmp(buf + i, ":do=", 4)) {
47232689Sbostic 					tc_gets(buf + i, &DO);
47332689Sbostic 				} else if (!strncmp(buf + i, ":vs=", 4)) {
47432689Sbostic 					tc_gets(buf + i, &VS);
47532689Sbostic 				} else if (!strncmp(buf + i, ":ve=", 4)) {
47632689Sbostic 					tc_gets(buf + i, &VE);
47732689Sbostic 				} else if (!strncmp(buf + i, ":ti=", 4)) {
47832689Sbostic 					tc_gets(buf + i, &TI);
47932689Sbostic 				} else if (!strncmp(buf + i, ":te=", 4)) {
48032689Sbostic 					tc_gets(buf + i, &TE);
48132689Sbostic 				} else if (!strncmp(buf + i, ":vs=", 4)) {
48232689Sbostic 					tc_gets(buf + i, &VS);
48332689Sbostic 				} else if (!strncmp(buf + i, ":ve=", 4)) {
48432689Sbostic 					tc_gets(buf + i, &VE);
48532689Sbostic 				} else if (!strncmp(buf + i, ":so=", 4)) {
48632689Sbostic 					tc_gets(buf + i, &SO);
48732689Sbostic 				} else if (!strncmp(buf + i, ":se=", 4)) {
48832689Sbostic 					tc_gets(buf + i, &SE);
48932689Sbostic 				} else if (!strncmp(buf + i, ":li#", 4)) {
49032689Sbostic 					tc_gnum(buf + i, &LINES);
49132689Sbostic 				} else if (!strncmp(buf + i, ":co#", 4)) {
49232689Sbostic 					tc_gnum(buf + i, &COLS);
49332689Sbostic 				}
49432689Sbostic 				i++;
49532689Sbostic 			}
49632689Sbostic 		}
49732689Sbostic 	} while (fgets(buf, BUFLEN, fp) != NULL);
49832689Sbostic 
49932689Sbostic 	if ((!CM) || (!CL)) {
50032689Sbostic 		clean_up("Terminal and termcap must have cm and cl");
50132689Sbostic 	}
50232689Sbostic 	tc_cmget();
50332689Sbostic }
50432689Sbostic 
tc_gets(ibuf,tcstr)50532689Sbostic tc_gets(ibuf, tcstr)
50632689Sbostic char *ibuf;
50732689Sbostic char **tcstr;
50832689Sbostic {
50932689Sbostic 	short i, j, k, n;
51032689Sbostic 	char obuf[BUFLEN];
51132689Sbostic 
51232689Sbostic 	i = 4;
51332689Sbostic 	j = 0;
51432689Sbostic 
51532689Sbostic 	while (ibuf[i] && is_digit(ibuf[i])) {
51632689Sbostic 		i++;
51732689Sbostic 	}
51832689Sbostic 
51932689Sbostic 	while (ibuf[i] && (ibuf[i] != ':')) {
52032689Sbostic 		if (ibuf[i] == '\\') {
52132689Sbostic 			i++;
52232689Sbostic 			switch(ibuf[i]) {
52332689Sbostic 			case 'E':
52432689Sbostic 				obuf[j] = ESC;
52532689Sbostic 				i++;
52632689Sbostic 				break;
52732689Sbostic 			case 'n':
52832689Sbostic 				obuf[j] = LF;
52932689Sbostic 				i++;
53032689Sbostic 				break;
53132689Sbostic 			case 'r':
53232689Sbostic 				obuf[j] = CR;
53332689Sbostic 				i++;
53432689Sbostic 				break;
53532689Sbostic 			case 'b':
53632689Sbostic 				obuf[j] = BS;
53732689Sbostic 				i++;
53832689Sbostic 				break;
53932689Sbostic 			case 't':
54032689Sbostic 				obuf[j] = TAB;
54132689Sbostic 				i++;
54232689Sbostic 				break;
54332689Sbostic 			case '0':
54432689Sbostic 			case '1':
54532689Sbostic 			case '2':
54632689Sbostic 			case '3':
54732689Sbostic 			case '4':
54832689Sbostic 			case '5':
54932689Sbostic 			case '6':
55032689Sbostic 			case '7':
55132689Sbostic 			case '8':
55232689Sbostic 			case '9':
55332689Sbostic 				n = 0;
55432689Sbostic 				k = 0;
55532689Sbostic 				while (k < 3 && ibuf[i] && is_digit(ibuf[i])) {
55632689Sbostic 					n = (8 * n) + (ibuf[i] - '0');
55732689Sbostic 					i++;
55832689Sbostic 					k++;
55932689Sbostic 				}
56032689Sbostic 				obuf[j] = (char) n;
56132689Sbostic 				break;
56232689Sbostic 			default:
56332689Sbostic 				obuf[j] = ibuf[i];
56432689Sbostic 				i++;
56532689Sbostic 			}
56632689Sbostic 		} else if (ibuf[i] == '^') {
56732689Sbostic 			obuf[j] = ibuf[i+1] - 64;
56832689Sbostic 			i += 2;
56932689Sbostic 		} else {
57032689Sbostic 			obuf[j] = ibuf[i++];
57132689Sbostic 		}
57232689Sbostic 		j++;
57332689Sbostic 	}
57432689Sbostic 	obuf[j] = 0;
57532689Sbostic 	if (!(*tcstr = md_malloc(j + 1))) {
57632689Sbostic 		clean_up("cannot alloc() memory");
57732689Sbostic 	}
57832689Sbostic 	(void) strcpy(*tcstr, obuf);
57932689Sbostic }
58032689Sbostic 
tc_gnum(ibuf,n)58132689Sbostic tc_gnum(ibuf, n)
58232689Sbostic char *ibuf;
58332689Sbostic int *n;
58432689Sbostic {
58532689Sbostic 	short i;
58632689Sbostic 	int r = 0;
58732689Sbostic 
58832689Sbostic 	i = 4;
58932689Sbostic 
59032689Sbostic 	while (is_digit(ibuf[i])) {
59132689Sbostic 		r = (r * 10) + (ibuf[i] - '0');
59232689Sbostic 		i++;
59332689Sbostic 	}
59432689Sbostic 	*n = r;
59532689Sbostic }
59632689Sbostic 
tstp()59732689Sbostic tstp()
59832689Sbostic {
59932689Sbostic 	endwin();
60032689Sbostic 	md_tstp();
60132689Sbostic 
60232689Sbostic 	start_window();
60332689Sbostic 	printf("%s%s", TI, VS);
60432689Sbostic 	wrefresh(curscr);
60532689Sbostic 	md_slurp();
60632689Sbostic }
60732689Sbostic 
tc_cmget()60832689Sbostic tc_cmget()
60932689Sbostic {
61032689Sbostic 	short i = 0, j = 0, rc_spec = 0;
61132689Sbostic 
61232689Sbostic 	while (CM[i] && (CM[i] != '%') && (j < 15)) {
61332689Sbostic 		cm_esc[j++] = CM[i++];
61432689Sbostic 	}
61532689Sbostic 	cm_esc[j] = 0;
61632689Sbostic 
61732689Sbostic 	while (CM[i] && (rc_spec < 2)) {
61832689Sbostic 		if (CM[i] == '%') {
61932689Sbostic 			i++;
62032689Sbostic 			switch(CM[i]) {
62132689Sbostic 			case 'd':
62232689Sbostic 				rc_spec++;
62332689Sbostic 				break;
62432689Sbostic 			case 'i':
62532689Sbostic 				cm_inc = 1;
62632689Sbostic 				break;
62732689Sbostic 			case '2':
62832689Sbostic 				cm_two = 1;
62932689Sbostic 				rc_spec++;
63032689Sbostic 				break;
63132689Sbostic 			case '3':
63232689Sbostic 				cm_three = 1;
63332689Sbostic 				rc_spec++;
63432689Sbostic 				break;
63532689Sbostic 			case '.':
63632689Sbostic 				cm_char = 1;
63732689Sbostic 				rc_spec++;
63832689Sbostic 				break;
63932689Sbostic 			case 'r':
64032689Sbostic 				cm_reverse = 1;
64132689Sbostic 				break;
64232689Sbostic 			case '+':
64332689Sbostic 				i++;
64432689Sbostic 				cm_inc = CM[i];
64532689Sbostic 				cm_char = 1;
64632689Sbostic 				rc_spec++;
64732689Sbostic 				break;
64832689Sbostic 			}
64932689Sbostic 			i++;
65032689Sbostic 		} else {
65132689Sbostic 			j = 0;
65232689Sbostic 			while (CM[i] && (CM[i] != '%')) {
65332689Sbostic 				cm_sep[j++] = CM[i++];
65432689Sbostic 			}
65532689Sbostic 			cm_sep[j] = 0;
65632689Sbostic 		}
65732689Sbostic 	}
65832689Sbostic 
65932689Sbostic 	j = 0;
66032689Sbostic 	if (rc_spec == 2) {
66132689Sbostic 		while (CM[i] && (j < 15)) {
66232689Sbostic 			cm_end[j++] = CM[i++];
66332689Sbostic 		}
66432689Sbostic 	}
66532689Sbostic 	cm_end[j] = 0;
66632689Sbostic }
66732689Sbostic 
66832689Sbostic #endif
669