[comp.sources.misc] v07i048: CRISP release 1.9 part 27/32

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (06/22/89)

Posting-number: Volume 7, Issue 48
Submitted-by: fox@marlow.UUCP (Paul Fox)
Archive-name: crisp1.9/part28



#!/bin/sh
# this is part 7 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file ./m_buf.c continued
#
CurArch=7
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file ./m_buf.c"
sed 's/^X//' << 'SHAR_EOF' >> ./m_buf.c
X		}
X	else if (i == LEFT) {
X		curwp->w_x = adj_wp->w_x;
X		curwp->w_w += adj_wp->w_w + 1;
X		}
X	else if (i == RIGHT) {
X		curwp->w_w += adj_wp->w_w + 1;
X		}
X
X	if (--adj_wp->w_bufp->b_nwnd == 0) {
X		adj_wp->w_bufp->b_line = adj_wp->w_line;
X		adj_wp->w_bufp->b_col = adj_wp->w_col;
X		}
X	if (wheadp == adj_wp)
X		wheadp = adj_wp->w_wndp;
X	else
X		for (nwp = wheadp; nwp; nwp = nwp->w_wndp)
X			if (nwp->w_wndp == adj_wp) {
X				nwp->w_wndp = adj_wp->w_wndp;
X				break;
X				}
X
X	chk_free((char *) adj_wp);
X
X	win_modify(WFHARD);
X	update();
X
X	accumulator = 0;
X	return 0;
X}
XWINDOW	*
Xget_edge(i)
X{	register WINDOW	*wp;
X
X	if (i == 0)
X		return NULL;
X
X	if (i == UP || i == DOWN) {
X		for (wp = wheadp; wp; wp = wp->w_wndp)
X			if (wp->w_w == curwp->w_w &&
X			    wp->w_x == curwp->w_x &&
X		    ((i == UP && wp->w_y + wp->w_h + 1 == curwp->w_y) ||
X		     (i == DOWN && curwp->w_y + curwp->w_h + 1 == wp->w_y)))
X				return wp;
X		}
X	else {
X		for (wp = wheadp; wp; wp = wp->w_wndp)
X			if (wp->w_h == curwp->w_h &&
X			    wp->w_y == curwp->w_y &&
X		 ((i == LEFT && wp->w_x + wp->w_w + 1 == curwp->w_x) ||
X		  (i == RIGHT && curwp->w_x + curwp->w_w + 1 == wp->w_x)))
X			return wp;
X		}
X	errorf("Edge does not have just two adjoining windows.");
X	return NULL;
X}
Xmove_edge()
X{	register int i = get_dir("Select an edge to move");
X	int	ch;
X	WINDOW	*adj_wp;
X
X	accumulator = 0;
X	if ((adj_wp = get_edge(i)) == NULL)
X		return 0;
X
X	accumulator = 1;
X	ewprintf("Move to new edge position and press Enter.");
X	while ((ch = getkey()) != CTRL_M) {
X		if (i == UP) {
X			if (ch == KEY_UP && adj_wp->w_h > 1) {
X				curwp->w_y--;
X				curwp->w_h++;
X				adj_wp->w_h--;
X				}
X			else if (ch == KEY_DOWN && curwp->w_h > 1) {
X				adj_wp->w_h++;
X				curwp->w_y++;
X				curwp->w_h--;
X				}
X			}
X		else if (i == DOWN) {
X			if (ch == KEY_DOWN && adj_wp->w_h > 1) {
X				curwp->w_h++;
X				adj_wp->w_y++;
X				adj_wp->w_h--;
X				}
X			else if (ch == KEY_UP && curwp->w_h > 1) {
X				adj_wp->w_h++;
X				adj_wp->w_y--;
X				curwp->w_h--;
X				}
X			}
X		else if (i == LEFT) {
X			if (ch == KEY_LEFT && adj_wp->w_w > 16) {
X				adj_wp->w_w--;
X				curwp->w_w++;
X				curwp->w_x--;
X				}
X			else if (ch == KEY_RIGHT && curwp->w_w > 16) {
X				adj_wp->w_w++;
X				curwp->w_w--;
X				curwp->w_x++;
X				}
X			}
X		else if (i == RIGHT) {
X			if (ch == KEY_RIGHT && adj_wp->w_w > 16) {
X				adj_wp->w_w--;
X				adj_wp->w_x++;
X				curwp->w_w++;
X				}
X			else if (ch == KEY_LEFT && curwp->w_w > 16) {
X				adj_wp->w_w++;
X				adj_wp->w_x--;
X				curwp->w_w--;
X				}
X			}
X		adj_wp->w_flag |= WFHARD;
X		win_modify(WFHARD);
X		update();
X		}
X	ewprintf("");
X	return 0;
X}
Xchange_window()
X{	register int	i;
X	WINDOW	*wp;
X
X	accumulator = 0;
X	set_buffer_parms(curwp, curbp);
X	if ((i = get_dir("Point to destination")) == 0)
X		return 0;
X	if (wp = get_window(i)) {
X		curwp->w_flag |= WFHARD;
X		wp->w_flag |= WFHARD;
X		curwp = wp;
X		curbp = curwp->w_bufp;
X		}
X	return 0;
X}
XWINDOW	*
Xget_window(i)
X{
X	WINDOW	*wp;
X	WINDOW	*new_wp = NULL;
X
X	if (i == UP) {
X		u_int16 col = *cur_col + curwp->w_x - curwp->w_indent;
X		for (wp = wheadp; wp; wp = wp->w_wndp) {
X			if (wp == curwp)
X				continue;
X			if (wp->w_x <= col && wp->w_x + wp->w_w >= col &&
X			    wp->w_y < curwp->w_y) {
X				if (new_wp == NULL)
X					new_wp = wp;
X				else if (new_wp->w_y < wp->w_y)
X					new_wp = wp;
X				}
X			}
X		}
X	else if (i == DOWN) {
X		u_int16 col = *cur_col + curwp->w_x - curwp->w_indent;
X		for (wp = wheadp; wp; wp = wp->w_wndp) {
X			if (wp == curwp)
X				continue;
X			if (wp->w_x <= col && wp->w_x + wp->w_w >= col &&
X			    wp->w_y > curwp->w_y) {
X				if (new_wp == NULL)
X					new_wp = wp;
X				else if (new_wp->w_y > wp->w_y)
X					new_wp = wp;
X				}
X			}
X		}
X	else if (i == LEFT) {
X		int	line = curwp->w_y + (curwp->w_line - curwp->w_top_line) + 1;
X		for (wp = wheadp; wp; wp = wp->w_wndp) {
X			if (wp == curwp)
X				continue;
X			if (wp->w_y <= line && wp->w_y + wp->w_h >= line &&
X			    wp->w_x < curwp->w_x) {
X				if (new_wp == NULL)
X					new_wp = wp;
X				else if (new_wp->w_x < wp->w_x)
X					new_wp = wp;
X				}
X			}
X		}
X	else if (i == RIGHT) {
X		int	line = curwp->w_y + (curwp->w_line - curwp->w_top_line) + 1;
X		for (wp = wheadp; wp; wp = wp->w_wndp) {
X			if (wp == curwp)
X				continue;
X			if (wp->w_y <= line && wp->w_y + wp->w_h >= line &&
X			    wp->w_x > curwp->w_x) {
X				if (new_wp == NULL)
X					new_wp = wp;
X				else if (new_wp->w_x > wp->w_x)
X					new_wp = wp;
X				}
X			}
X		}
X	if (new_wp) {
X		accumulator = 1;
X		return new_wp;
X		}
X	errorf("No window there.");
X	accumulator = 0;
X	return 0;
X}
Xsave_position()
X{	extern char *chk_alloc();
X	struct pos *pos = (struct pos *) chk_alloc(sizeof (struct pos));
X
X	if (hd_position == NULL)
X		hd_position = ll_init();
X	pos->buffer = curbp->b_bufnum;
X	pos->line = *cur_line;
X	pos->col = *cur_col;
X	pos->top_line = curwp->w_bufp == curbp ? curwp->w_top_line : -1;
X	ll_push(hd_position, (char *) pos);
X	return 0;
X}
Xrestore_position()
X{
X	struct pos *pos = NULL;
X	List_p lp;
X	BUFFER	*saved_bp = curbp;
X
X	if (hd_position == NULL)
X		hd_position = ll_init();
X
X	lp = ll_first(hd_position);
X	if (lp == NULL) {
X		accumulator = 0;
X		errorf("restore_position: no saved position.");
X		return 0;
X		}
X	pos = (struct pos *) ll_elem(lp);
X	ll_pop(hd_position);
X
X	if ((argv[1].l_flags == F_NULL || argv[1].l_int) && pos) {
X		argv[1].l_flags = argv[2].l_flags = F_INT;
X		argv[1].l_int = pos->line;
X		argv[2].l_int = pos->col;
X		if (curbp = numberb(pos->buffer)) {
X			set_hooked();
X			move_abs();
X			if (curwp->w_bufp == curbp)
X				curwp->w_top_line = pos->top_line;
X			curbp = saved_bp;
X			set_hooked();
X			}
X		}
X	accumulator = 1;
X	return 0;
X}
X
Xinq_views()
X{	BUFFER *bp;
X
X	accumulator = 0;
X	if (argv[1].l_flags == F_INT) {
X		bp = numberb((u_int16) argv[1].l_int);
X		if (bp)
X			accumulator = bp->b_nwnd;
X		}
X	else
X		accumulator = curbp->b_nwnd;
X	return 0;
X}
Xinq_lines()
X{
X	accumulator = curbp->b_numlines - 1;
X}
Xstatic
Xsort_compare(line1, line2)
XLINE	*line1, *line2;
X{	int	len = line1->l_used;
X	int	ret;
X	register unsigned char *cp1 = ltext(line1);
X	register unsigned char *cp2 = ltext(line2);
X
X	if (line2->l_used < len)
X		len = line2->l_used;
X	while (len-- > 0) {
X		ret = *cp1++ - *cp2++;
X		if (ret)
X			return ret;
X		}
X
X	return line1->l_used - line2->l_used;
X}
Xsort_buffer()
X{	int	num_lines;
X	extern int	start_line, end_line;
X	LINE	*lp, *clp;
X	register int i;
X
X	if (get_marked_areas((WINDOW *) NULL) == FALSE) {
X		start_line = 1;
X		end_line--;
X		}
X	num_lines = end_line - start_line + 1;
X	lp = (LINE *) chk_alloc(num_lines * sizeof (LINE));
X	for (i = 0; i < num_lines; i++) {
X		clp = vm_lock_line(start_line + i);
X		lp[i] = *clp;
X		}
X	qsort(lp, num_lines, sizeof (LINE), sort_compare);
X	for (i = 0; i < num_lines; i++) {
X		clp = vm_lock_line(start_line + i);
X		clp->l_size = lp[i].l_size;
X		clp->l_used = lp[i].l_used;
X		clp->l_lineno = lp[i].l_lineno;
X		clp->l_flags = lp[i].l_flags;
X		clp->l_text = lp[i].l_text;
X		}
X	win_modify(WFHARD);
X}
SHAR_EOF
echo "File ./m_buf.c is complete"
chmod 0444 ./m_buf.c || echo "restore of ./m_buf.c fails"
mkdir . >/dev/null 2>&1
echo "x - extracting ./m_msg.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ./m_msg.c &&
X/**************************************************************
X *
X *	CRISP - Custom Reduced Instruction Set Programmers Editor
X *
X *	(C) Paul Fox, 1989
X *	43, Jerome Close	      Tel: +44 6284 4222
X *	    Marlow
X *	     Bucks.
X *		England SL7 1TX
X *
X *
X *    Please See COPYRIGHT notice.
X *
X **************************************************************/
X# include	"list.h"
X
X
XSCCSID("@(#) m_msg.c 1.7, (C) 1989, P. Fox");
X
Xint	p_on_error = 0;
Xstatic int	offset = 0;
Xextern	int	pcolor;
X
Xchar	*
Xdo__prntf()
X{	char	str[BUFSIZ];
X	static char	buf[256];
X	register char	*cp;
X	int	arg;
X	int	i;
X
X	strcpy(str, get_str(offset + 1));
X
X	for (arg = offset + 2, cp = str; *cp; ) {
X		if (*cp != '%') {
X			cp++;
X			continue;
X			}
X		if (cp[1] == '%') {
X			cp += 2;
X			continue;
X			}
X		if (cp[1] == '-')
X			cp++;
X		while (isdigit(cp[1]))
X			cp++;
X		if (cp[1] == 'd') {
X			cp++;
X			strcpy(buf, cp);
X			*cp++ = 'l';
X			strcpy(cp, buf);
X			}
X		if (cp[1] == 's')
X			argv[arg].l_int = (long) get_str(arg);
X		if (cp[1] == 'c') {
X			*cp = (char) argv[arg].l_int;
X			strcpy(cp+1, cp+2);
X			for (i = arg; i < MAX_ARGC-1; i++)
X				argv[i] = argv[i+1];
X			arg--;
X			}
X		arg++;
X		cp++;
X		}
X
X	sprintf(buf, str, argv[offset + 2].l_int, argv[offset + 3].l_int, 
X		argv[offset + 4].l_int, 
X		argv[offset + 5].l_int, 
X		argv[offset + 6].l_int,
X		argv[offset + 7].l_int, 
X		argv[offset + 8].l_int, 
X		argv[offset + 9].l_int,
X		argv[offset + 10].l_int);
X	return buf;
X
X}
X/*----------------------------------------------------------------
X *
X *   (message format_string [value1] ...)
X *
X *   Function:
X *
X *	This macro is used to display a message on the status line.
X *      It takes a variable number of paramaters, the first of which
X *	is a printf-like string. The message is displayed on the status
X *      line.
X *
X *      All parameters are evaluated, even if they are not needed.
X *
X *   Examples:
X *
X *	(message "The value of variable i = %d"  i)
X *
X *      (message "File: %s"  current_file_name)
X *
X *----------------------------------------------------------------*/
Xmessage()
X{
X	msg_error();
X/*	if (hooked)
X		set_cursor();*/
X	return 0;
X}
Xdo_error()
X{
X	return msg_error();
X}
Xmsg_error()
X{
X	char	*cp = do__prntf();
X
X	if (cp) {
X		if (p_on_error) {
X			strcat(cp, "..");
X			ewputs(cp, (char *) NULL);
X			getkey();
X			}
X		else
X			ewputs(cp, (char *) NULL);
X		return 0;
X		}
X	return -1;
X}
X/*----------------------------------------------------------------
X *
X *   (printf format_string [value1] ...)
X *   Macro:		printf
X *
X *   Function:
X *
X *	This macro is used to print debugging messages on stdout.
X *      format_string is a C printf() string, containing the following
X *	set of %-sequences. [value1] ... are the optional parameters
X *      used to satisfy the %-escapes.
X *
X *      All parameters are evaluated, even if they are not needed.
X *
X *	%c	Print parameter as an ASCII character.
X *	%d	Print parameter in decimal.
X *	%x	Print parameter in hex.
X *	%s	Print argument as a string.
X *
X *   Examples:
X *
X *	(printf "Current directory %s"  (get_current_directory))
X *
X *      (printf "Performed %02d iterations"  count)
X *
X *----------------------------------------------------------------*/
Xdo_printf()
X{
X	char *cp = do__prntf();
X	if (cp) {
X		printf("%s", cp);
X		fflush(stdout);
X		return 0;
X		}
X	return -1;
X}
Xdo_sprintf()
X{
X	char *cp;
X	SYMBOL	*sp = argv[1].l_sym;
X	offset = 1;
X	cp = do__prntf();
X	offset = 0;
X	if (cp) {
X		str_assign(sp, cp);
X		return 0;
X		}
X	return -1;
X}
Xpause_on_error()
X{
X	p_on_error = argv[1].l_flags == F_INT ? argv[1].l_int : !p_on_error;
X	ewprintf("Pausing errors %s.", p_on_error ? "on" : "off");
X	return 0;
X}
Xstatic void
Xpf(str, a, b, c, d, e, f)
Xchar	*str;
Xchar	*a, *b, *c, *d, *e, *f;
X{	char	buf[BUFSIZ];
X
X	sprintf(buf, str, a, b, c, d, e, f);
X	if (p_on_error) {
X		strcat(buf, "..");
X		ewputs(buf, (char *) NULL);
X		(void) getkey();
X		}
X	else
X		ewputs(buf, (char *) NULL);
X}
X/* VARARGS1 */
Xvoid
Xinfof(str, a, b, c, d, e, f)
Xchar	*str;
Xchar	*a, *b, *c, *d, *e, *f;
X{
X	if (msg_level == 0)
X		ewprintf(str, a, b, c, d, e, f);
X}
X/* VARARGS1 */
Xvoid
Xerrorf(str, a, b, c, d, e, f)
Xchar	*str;
Xchar	*a, *b, *c, *d, *e, *f;
X{
X	if (msg_level <= 2) {
X		pcolor = CERROR;
X		pf(str, a, b, c, d, e, f);
X		pcolor = CMESSAGE;
X		}
X}
X
SHAR_EOF
chmod 0444 ./m_msg.c || echo "restore of ./m_msg.c fails"
mkdir . >/dev/null 2>&1
echo "x - extracting ./mac1.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ./mac1.c &&
X/**************************************************************
X *
X *	CRISP - Custom Reduced Instruction Set Programmers Editor
X *
X *	(C) Paul Fox, 1989
X *	43, Jerome Close	      Tel: +44 6284 4222
X *	    Marlow
X *	     Bucks.
X *		England SL7 1TX
X *
X *
X *    Please See COPYRIGHT notice.
X *
X **************************************************************/
X# include	"list.h"
X# include	"clk.h"
X
XSCCSID("@(#) mac1.c 1.14, (C) P. Fox");
X
Xint	imode = TRUE;
Xint	break_flag = FALSE;
Xint	cont_flag = FALSE;
Xint	while_count = 0;
Xint	tab_char = TRUE;
Xint	doing_selfinsert = FALSE;	/* Used by undo collapser.	*/
Xstatic char	cwd[80] = {0};
XCOLOR	tmp_col_table;
Xextern char	character;
Xextern	char	*strtok();
Xstruct	colp {
X	int	max;
X	u_int16	*arg;
X	char	*msg;
X	} col_msg[] = {
X		16,	&tmp_col_table.c_background,	"dbackground",
X		16,	&tmp_col_table.c_normal,	"dforeground",
X		16,	&tmp_col_table.c_select,        "dselected title",
X		16,	&tmp_col_table.c_messages,     	"dnormal message",
X		16,	&tmp_col_table.c_error, 	"derror message",
X		256,	&tmp_col_table.c_fg,		"xhighlight",
X		0
X		};
X# ifdef SYSV
X# define	CRISP
X# include	"utils/getcwd.c"
X# endif
Xstrip_cr()
X{	extern int strip_cr_flag;
X	accumulator = strip_cr_flag = argv[1].l_flags == F_INT ? argv[1].l_int : !strip_cr_flag;
X	infof("<CR> %sstripped from input files.", strip_cr_flag ? "" : "not ");
X}
Xinq_called()
X{
X	strl_acc_assign(ms_cnt <= 1 ? "" : mac_stack[ms_cnt-2].name);
X	return 0;
X}
Xdel()
X{
X	accumulator = unlink(get_str(1)) == 0;
X	return 0;
X}
Xset_top_left()
X{
X	if (hooked && argv[1].l_flags == F_INT) {
X		int new_top_line = argv[1].l_int > curbp->b_numlines ?
X				    curbp->b_numlines : argv[1].l_int;
X		if (new_top_line < 0)
X			new_top_line = 1;
X		if (new_top_line != curwp->w_top_line) {
X			curwp->w_top_line = new_top_line;
X			win_modify(WFHARD);
X			}
X		}
X	return 0;
X}
Xdel_to_eol()
X{	LINE	*lp = linep(*cur_line);
X	int	col = current_offset(*cur_col, FALSE);
X	RSIZE	n = llength(lp) - col;
X	if (n > 0)
X		ldelete(n);
X	return 0;
X}
Xcolor()
X{	register struct colp *colp;
X	int	col = 1;
X	int	ask = argv[1].l_flags == F_NULL;
X	char	buf[80];
X	char	buf1[80];
X	int	val;
X
X	tmp_col_table = col_table;
X	tmp_col_table.c_fg = (col_table.c_bg << 4) | col_table.c_fg;
X	for (colp = col_msg; colp->msg; colp++, col++) {
X		char	*msg = colp->msg;
X		int	hex = *msg++ == 'x';
X		if (ask) {
X			val = *colp->arg;
X			sprintf(buf1, "Enter %s color number <", msg);
X			sprintf(buf1+strlen(buf1), hex ? "0x%02x>: " : "%d>: ", val);
X			if (ereply(buf1, buf, sizeof buf) != TRUE)
X				return 0;
X			if (buf[0] != NULL) {
X				if (hex)
X					sscanf(buf, "%x", &val);
X				else
X					val = atoi(buf);
X				}
X			}
X		else
X			val = argv[col].l_flags == F_INT ? argv[col].l_int : -1;
X		if (val >= colp->max) {
X			errorf("Invalid color: must be 0-%d.", colp->max-1);
X			return 0;
X			}
X		if (val >= 0)
X			*colp->arg = val;
X		}
X	col_table = tmp_col_table;
X	col_table.c_bg = (col_table.c_fg >> 4) & 7;
X	col_table.c_fg &= 0x0f;
X	vtblanks();
X	sgarbf = TRUE;
X	return 0;
X}
Xinq_mode()
X{
X	accumulator = imode;
X	return 0;
X}
Xinq_macro()
X{	extern	MACRO	*lookup_macro();
X
X	accumulator = lookup_macro(get_str(1)) != NULL;
X	return 0;
X}
Xins_mode()
X{
X	accumulator = imode;
X	if (argv[1].l_flags == F_NULL)
X		imode = !imode;
X	else
X		imode = (int) argv[1].l_flags;
X	line_col(TRUE);
X	print_cursor(imode);
X	return 0;
X}
Xexist()
X{	struct stat stat_buf;
X	extern int stat();
X
X	if (stat(get_str(1), &stat_buf) < 0)
X		accumulator = 0;
X	else
X		accumulator = 1;
X	return 0;
X}
X		
Xset_msg_level()
X{
X	msg_level = (int) argv[1].l_int;
X	return 0;
X}
Xinq_msg_level()
X{
X	accumulator = (long) msg_level;
X	return 0;
X}
Xdel_char()
X{	int n = argv[1].l_flags == F_INT ? argv[1].l_int : 1;
X
X	if (n > 0) {
X		current_offset(*cur_col, TRUE);
X		ldelete((RSIZE) n);
X		}
X	return 0;
X}
Xbackspace()
X{
X
X	if (imode) {
X		argv[1].l_flags = F_INT;
X		argv[1].l_int = 1;
X		prev_char(1);
X		if (accumulator == 0)
X			return 0;
X		ldelete((RSIZE) 1);
X		}
X	else {
X		backchar(1);
X		if (!tab_replace())
X			ldelete((RSIZE) 1);
X		if (!imode) {
X			l_insert(' ');
X			backchar(1);
X			}
X		}
X	return 0;
X}
Xdel_line()
X{	LINE	*lp = linep(*cur_line);
X	int	saved_col = *cur_col;
X	*cur_col = 1;
X	ldelete((RSIZE) (llength(lp) + 1));
X	*cur_col = saved_col;
X	return 0;
X}
Xexec_cmd()
X{	char	*cp;
X	int	ret_code;
X	LIST	list[16];
X	extern	char	*strchr();
X	char	buf[BUFSIZ];
X	char	*arg;
X
X	if (argv[1].l_flags == F_NULL) {
X		if ((cp = get_arg1("Command: ", buf, sizeof buf)) == NULL)
X			return -1;
X		return str_exec(cp);
X		}
X	arg = get_str(1);
X	if (arg[0] == NULL)
X		return 0;
X	if (strchr(arg, ' '))
X		return str_exec(arg);
X	nest_level++;
X	list[0] = F_STR;
X	LPUT32(list, (long) arg);
X	list[5] = F_HALT;
X	ret_code = exec1(list, argv[2].l_list ? argv[2].l_list : &list[5]);
X	delete_local_symbols();
X	return ret_code;
X}
Xget_parm()
X{	LIST *next_atom();
X	int	length = 0;
X	char	reply[80];
X	SYMBOL	*sp = argv[2].l_sym;
X	LIST	*lp;
X	SPTREE	*saved_level;
X	int	i;
X	int	type;
X	char	*def = "";
X	char	numbuf[10];
X	LISTV	lpv;
X	
X
X	accumulator = 0;
X	length = argv[4].l_flags == F_NULL ? sizeof reply - 1 : argv[4].l_int;
X	if (sp->s_type == F_STR)
X		def = get_str(5);
X	else
X		sprintf(def = numbuf, "%ld", argv[4].l_int);
X
X	if (argv[1].l_flags == F_NULL) {
Xre_prompt:
X		if (argv[3].l_flags == F_NULL)
X			return;
X		if (edefreply(get_str(3), def, reply, length) != TRUE) {
X			accumulator = 0;
X			return;
X			}
X		accumulator = 1;
X		if (sp->s_type == F_STR) {
X			reply[length] = NULL;
X			str_assign(sp, reply);
X			}
X		else
X			sscanf(reply, "%ld", &sp->s_int);
X		return;
X
X		}
X	i = (int) argv[1].l_int;
X	for (lp = mac_stack[ms_cnt-1].argv; lp && i > 0 && *lp != F_HALT; i--)
X		lp = next_atom(lp);
X	if (lp == NULL || *lp == F_HALT)
X		goto re_prompt;
X
X	saved_level = lsym_tbl[nest_level];
X	lsym_tbl[nest_level--] = spinit();
X	type = eval(lp, &lpv);
X	chk_free((char *) lsym_tbl[++nest_level]);
X	lsym_tbl[nest_level] = saved_level;
X
X	if (lpv.l_flags == F_NULL)
X		return;
X		
X	argv[2] = lpv;
X	com_equ1(NOOP, sp);
X	accumulator = 1;
X	acc_type = F_INT;
X}
Xput_parm()
X{	LIST	*lp;
X	int	i = (int) argv[1].l_int;
X	SYMBOL	*sp;
X
X	accumulator = 0;
X	for (lp = mac_stack[ms_cnt-1].argv; i-- > 0 && *lp != F_HALT; )
X		if (*lp == F_LIST)
X			lp += LGET16(lp);
X		else
X			lp += sizeof_atoms[*lp];
X	if (*lp != F_HALT && *lp == F_STR) {
X		SPTREE *saved_level = lsym_tbl[nest_level];
X		lsym_tbl[nest_level--] = spinit();
X		sp = lookup((char *) LGET32(lp));
X		chk_free((char *) lsym_tbl[++nest_level]);
X		lsym_tbl[nest_level] = saved_level;
X		if (sp->s_type == F_INT && argv[2].l_flags == F_INT) {
X			accumulator = 1;
X			int_assign(sp, argv[2].l_int);
X			}
X		else if (sp->s_type == F_STR && 
X		      (argv[2].l_flags == F_STR ||
X		       argv[2].l_flags == F_RSTR ||
X		       argv[2].l_flags == F_LIT)) {
X			accumulator = 1;
X			str_assign(sp, get_str(2));
X			}
X		}
X	return 0;
X}
Xchar	*
Xget_cwd()
X{	extern char *getcwd();
X
X	if (cwd[0])
X		return cwd;
X	getcwd(cwd, sizeof cwd);
X	return cwd;
X}
Xinq_names()
X{	char	*cp = curbp->b_fname;
Xextern	char	*strrchr();
Xextern	char	*bname();
X	char	*ext = strrchr(cp, '.');
X
X	if (argv[1].l_flags != F_NULL)
X		str_assign(argv[1].l_sym, cp);
X	if (argv[2].l_flags != F_NULL)
X		str_assign(argv[2].l_sym, ext ? ext+1 : "");
X	if (argv[3].l_flags != F_NULL)
X		str_assign(argv[3].l_sym, bname(cp));
X	return 0;
X		
X}
Xgoto_line()
X{	long	l;
X	int	old_line = *cur_line;
X
X	if (get_iarg1("Go to line: ", &l)) {
X		accumulator = -1;
X		return 0;
X		}
X
X	gotoline((int) l);
X	accumulator = old_line != *cur_line;
X	return 0;
X}
Xgoto_old_line()
X{	long	l;
X	register u_int16	i;
X	int	line_no = 1;
X	register LINE	*lp;
X	LINE	*target_lp = NULL;
X
X	if (get_iarg1("Go to old line: ", &l))
X		return 0;
X	i = (u_int16) l;
X	if (i == 0)
X		i = 1;
X	accumulator = 1;
X	for (lp = lforw(curbp->b_linep); lp != curbp->b_linep; lp = lforw(lp)) {
X		if (lp->l_lineno == i) {
Xgot_target:
X			u_dot();
X			win_modify(WFMOVE);
X			*cur_line = line_no;
X			win_modify(WFMOVE);
X			return 0;
X			}
X		if (lp->l_lineno > i)
X			target_lp = lp;
X		line_no++;
X		}
X	if (target_lp) {
X		line_no = target_lp->l_lineno;
X		goto got_target;
X		}
X
X	gotoline((int) l);
X	return 0;
X}
Xkey_down()
X{
X	return forwline(argv[1].l_flags == F_INT ? argv[1].l_int : 1);
X}
Xkey_left()
X{
X	return backchar(argv[1].l_flags == F_INT ? argv[1].l_int : 1);
X}
Xkey_right()
X{
X	return forwchar(argv[1].l_flags == F_INT ? argv[1].l_int : 1);
X}
Xkey_up()
X{
X	return backline(argv[1].l_flags == F_INT ? argv[1].l_int : 1);
X}
Xnothing()
X{
X	return 0;
X}
Xdo_while()
X{	LISTV	condition;
X	LISTV	statement;
X	LISTV	result;
X	extern int doing_return;
X
X	while_count++;	
X	condition = argv[1];
X	statement = argv[2];
X
X	break_flag = FALSE;
X	cont_flag = FALSE;
X	while (!doing_return && !break_flag &&
X		eval(condition.l_list, &result) == F_INT && result.l_int) {
X		if (statement.l_flags != F_NULL)
X			eval_expr(&statement);
X		if (cont_flag)
X			cont_flag = break_flag = FALSE;
X		}
X	while_count--;
X	break_flag = cont_flag = FALSE;
X	return 0;
X}
Xdo_break()
X{
X	if (while_count <= 0) {
X		errorf("break not executed in loop.");
X		return 0;
X		}
X	break_flag = TRUE;
X	return 0;
X}
Xdo_continue()
X{
X	break_flag = TRUE;
X	cont_flag = TRUE;
X	return 0;
X}
Xdo_switch()
X{	register LIST	*lp = argv[2].l_list;
X	register int	isint = argv[1].l_flags == F_INT;
X	LISTV	result;
X	long	l = argv[1].l_int;
X	char	*switch_item = get_str(1);
X	int	wildcard = FALSE;
X
X	while (*lp != F_HALT) {
X		char	*str = (char *) LGET32(lp);
X		int	type;
X		if (wildcard)
X			goto eval_it;
X		if (*lp == F_STR && strcmp(str, "NULL") == 0)
X			goto eval_it;
X		type = eval(lp, &result);
X		if (isint) {
X			if (type == F_INT && l == result.l_int)
X				goto eval_it;
X			goto nope;
X			}
X		if ((type == F_STR || type == F_LIT) 
X			&& strcmp(result.l_str, switch_item) == 0) 
X			goto eval_it;
X		if (type == F_RSTR && strcmp(result.l_rstr->r_str, switch_item) == 0) {
Xeval_it:
X			if (*lp == F_LIST)
X				lp += LGET16(lp);
X			else
X				lp += sizeof_atoms[*lp];
X			if (*lp != F_HALT) {
X				if (*lp == F_STR && strcmp(LGET32(lp), "NULL") == NULL) {
X					wildcard = TRUE;
X					goto match_next;
X					}
X				eval(lp, &result);
X				}
X			break;
X			}
Xnope:
X		if (*lp == F_LIST)
X			lp += LGET16(lp);
X		else
X			lp += sizeof_atoms[*lp];
Xmatch_next:
X		if (*lp == F_HALT)
X			break;
X		if (*lp == F_LIST) {
X			int i = LGET16(lp);
X			if (i == 0)
X				break;
X			lp += i;
X			}
X		else
X			lp += sizeof_atoms[*lp];
X		}
X	return 0;
X}
Xdo_if()
X{	LISTV	result;
X	LIST	*lp = NULL;
X
X	if (argv[1].l_int)
X		lp = argv[2].l_list;
X	else if (argc > 3)
X		lp = argv[3].l_list;
X	if (lp) {
X		eval(lp, &result);
X		if (acc_type == F_RSTR)
X			str_acc_assign(result.l_rstr->r_str, result.l_rstr->r_used);
X		}
X	return 0;
X}
Xdo_tabs()
X{	int	i;
X	u_int16	t;
X	int	prompting = argv[1].l_flags == F_NULL;
X	int	tab_stop;
X
X	if (prompting) {
X		for (argc = 1; argc < NTABS; ) {
X			char	buf[80];
X			if (ereply("Enter tab stop (return terminates): ", 
X			    buf, sizeof buf) != TRUE)
X				return;
X			if ((argv[argc].l_int = atol(buf)) == 0)
X				break;
X			argv[argc].l_flags = F_INT;
X			argv[++argc].l_flags = F_NULL;
X			}
X		}
X
X	curbp->b_tabs[0] = 0;
X	for (i = 1, tab_stop = 1; i < argc && tab_stop < NTABS; i++)
X		if (argv[i].l_flags != F_NULL && argv[i].l_int != 1) {
X			t = (u_int16) argv[i].l_int;
X			curbp->b_tabs[tab_stop-1] = t ? t - 1 : 0;
X			curbp->b_tabs[tab_stop] = 0;
X			tab_stop++;
X			}
X	win_modify(WFHARD);
X}
Xstatic int	old_line;
Xstatic int	old_col;
Xmove_rel()
X{	
X	win_modify(WFMOVE);
X	old_line = *cur_line;
X	old_col = *cur_col;
X	*cur_line += argv[1].l_int;
X	*cur_col += argv[2].l_int;
X	return check_bounds();
X}
Xcheck_bounds()
X{
X	if (*cur_col < 1)
X		*cur_col = 1;
X	if (*cur_line > curbp->b_numlines)
X		*cur_line = curbp->b_numlines;
X	else if (*cur_line < 1)
X		*cur_line = 1;
X	win_modify(WFMOVE);
X	if (*cur_line != old_line || *cur_col != old_col)
X		accumulator = 1;
X	else
X		accumulator = 0;
X	return 0;
X}
Xmove_abs()
X{
X	win_modify(WFMOVE);
X	old_line = *cur_line;
X	old_col = *cur_col;
X	if (argv[1].l_int)
X		*cur_line = argv[1].l_int;
X	if (argv[2].l_int)
X		*cur_col = argv[2].l_int;
X
X	return check_bounds();
X}
Xinsert(proc)
X{	char *cp = get_str(1);
X	long	n = argv[2].l_flags == F_INT ? argv[2].l_int : 1;
X	int	len = strlen(cp);
X
X	while (n-- > 0)
X		if (proc)
X			p_write(cp, len);
X		else
X			linsert(cp, len);
X	return 0;
X}
Xselfinsert()
X{	extern int tab_char;
X
X	if (argv[1].l_flags == F_INT)
X		character = argv[1].l_int;
X	if (!imode) {
X		if (character == '\t') {
X			u_dot();
X			*cur_col = next_tab_stop(*cur_col) + 1;
X/*			*cur_col = next_tab_stop(*cur_col + 1) + 1;*/
X			return 0;
X			}
X		if (character == '\r' || character == '\n') {
X			(void) forwline(1);	
X			*cur_col = 1;
X			return 0;
X			}
X		else {
X			LINE	*lp = linep(*cur_line);
X			if (!tab_replace())
X				if (current_offset(*cur_col, FALSE) < lp->l_used)
X					ldelete((RSIZE) 1);
X			}
X		}
X	doing_selfinsert = TRUE;
X	if (character == '\t' && tab_char == FALSE) {
X		int t = next_tab_stop(*cur_col) - *cur_col;
X		while (t-- >= 0)
X			l_insert(' ');
X		}
X	else if (character == '\r' || character == '\n')
X		lnewline(character);
X	else 
X		l_insert(character);
X	doing_selfinsert = FALSE;
X	curbp->b_uchar = character;
X	trigger(REG_TYPED);
X	return 0;
X}
Xdo_abort()
X{
X	ttclose();
X	return exit(1);
X}
Xdo_version()
X{
X	extern	char	*version;
X	extern int version_number;
X
X	ewprintf("%s", version);
X	accumulator = version_number;
X}
Xreturns(do_returns)
X{	extern int doing_return;
X
X	if (!do_returns)
X		doing_return = TRUE;
X
X	switch (argv[1].l_flags) {
X	  case F_INT:
X		accumulator = argv[1].l_int;
X		break;
X	  case F_STR:
X	  case F_RSTR:
X		strl_acc_assign(get_str(1));
X		break;
X	  case F_LIST: {
X		LIST *lp = (LIST *) get_str(1);
X		str_acc_assign(lp, length_of_list(lp));
X		acc_type = F_LIST;
X		break;
X		}
X	  }
X}
Xautoload()
X{	char	*module = get_str(1);
X	extern char *strdup();
X	extern MACRO *lookup_macro();
X	LIST	*lp;
X
X	for (lp = argv[2].l_list; *lp != F_HALT; ) {
X		LISTV	result;
X		int type = eval(lp, &result);
X		char	*macro_name;
X
X		if (type == F_LIT || type == F_STR)
X			macro_name = result.l_str;
X		else if (type == F_RSTR)
X			macro_name = result.l_rstr->r_str;
X		else
X			return 0;
X		if (lookup_macro(macro_name) == NULL)
X			ins_macro(macro_name, (LIST *) strdup(module), M_AUTOLOAD);
X/*else return 0;*/
X		if (*lp == F_LIST)
X			lp += LGET16(lp);
X		else
X			lp += sizeof_atoms[*lp];
X		}
X	return 0;
X}
Xload_macro()
X{	char	*filename;
X	char	buf[BUFSIZ];
X	extern int verbose_errors;
X
X	accumulator = 0;
X	if ((filename = get_arg1("Macro file: ", buf, sizeof buf)) == NULL)
X		return;
X	verbose_errors = FALSE;
X	if (ld_macro(filename) == 0) {
X		accumulator = 1;
X		infof("Macro file loaded successfully.");
X		}
X	acc_type = F_INT;
X}
Xld_macro(filename)
Xchar	*filename;
X{	int	ret;
X	char	buf[128];
X	char	buf1[128];
X	char	fn[80];
X	extern	char	*bpath;
X	extern char	*strchr(), *ggetenv();
X	extern	int m_flag;
X	char	*cp;
X	char	*home;
X	int	len = strlen(filename);
X
X	if (len > sizeof fn - 20)
X		goto error;
X	memcpy(fn, filename, len + 1);
X	if ((ret = read_macro(fn)) >= 0)
X		return ret;
X	if (fn[0] == '/')
X		goto error;
X	/*if (strchr(fn, '/') != NULL) {
X		if ((ret = read_macro(fn)) >= 0)
X			return ret;
X		goto error;
X		}*/
X
X	strcpy(buf1, bpath);
X	for (cp = strtok(buf1, ";"); cp; cp = strtok((char *) NULL, ";")) {
X		sprintf(buf, "%s/%s", cp, fn);
X		if ((ret = read_macro(buf)) >= 0)
X			return ret;
X		}
X	if ((home = ggetenv("HOME")) == NULL)
X		goto error;
X	sprintf(buf, "%s/%s", home, fn);
X	if ((ret = read_macro(buf)) >= 0)
X		return ret;
Xerror:
X	if (m_flag == FALSE)
X		infof("load_macro: file %s not found", fn);
X	return -1;
X}
Xinq_kbd_char()
X{
X	accumulator = typeahead();
X	return 0;
X}
Xread_char()
X{	extern int wait_flag;
X
X	update();
X	if (wait_flag)
X		accumulator = (long) getkey();
X	else
X		accumulator = typeahead() ? (long) getkey() : -1;
X	return 0;
X}
Xfirst_time()
X{	extern MACRO *lookup_macro();
X	MACRO	*mptr;
X
X	if (ms_cnt == 0) {
X		ewprintf("first_time: ms_cnt == 0 ?");
X		return -1;
X		}
X	mptr = lookup_macro(mac_stack[ms_cnt-1].name);
X	accumulator = mptr->m_ftime;
X	return 0;
X}
Xdo_upper()
X{	register char	*cp;
X
X	strl_acc_assign(get_str(1));
X
X	for (cp = saccumulator; *cp; cp++)
X		if (*cp >= 'a' && *cp <= 'z')
X			*cp -= 0x20;
X	return 0;
X}
Xdo_lower()
X{	register char	*cp;
X
X	strl_acc_assign(get_str(1));
X
X	for (cp = saccumulator; *cp; cp++)
X		if (*cp >= 'A' && *cp <= 'Z')
X			*cp += 0x20;
X	return 0;
X}
Xinq_environment()
X{	char	*cp;
X	extern	char	*ggetenv();
X
X	cp = ggetenv(get_str(1));
X	strl_acc_assign(cp ? cp : "");
X	return 0;
X}
Xdo_read()
X{	int	l = 32767;
X	char	*cp;
X	LINE	*lp = vm_lock_line(*cur_line);
X	int	offset = current_offset(*cur_col, FALSE);
X	int	len = llength(lp) - offset;
X	int	length_to_copy;
X
X	if (argv[1].l_flags != F_NULL)
X		l = (int) argv[1].l_int;
X
X	if (l < 0)
X		l = 1;
X	length_to_copy = l > len ? len : l;
X	if (length_to_copy) {
X		str_acc_assign(&lgetc(lp, offset), length_to_copy + 1);
X		cp = saccumulator + length_to_copy;
X		}
X	else {
X		str_acc_assign("\n", 1);
X		cp = saccumulator;
X		}
X	vm_unlock(*cur_line);
X	l -= length_to_copy;
X	if (l > 0)
X		*cp++ = '\n';
X	*cp = NULL;
X	return 0;
X}
Xinq_position()
X{
X	if (argv[1].l_flags != F_NULL)
X		argv[1].l_sym->s_int = *cur_line;
X	if (argv[2].l_flags != F_NULL)
X		argv[2].l_sym->s_int = *cur_col;
X
X	accumulator = *cur_line == curbp->b_numlines;
X
X	return 0;
X}
X
Xdo_getwd()
X{
X	str_assign(argv[2].l_sym, get_cwd());
X	accumulator = 1;
X	return 0;
X}
Xdo_cd()
X{	extern char *get_cwd();
X	if (argv[1].l_flags == F_NULL) {
X		ewprintf("%s", get_cwd());
X		return 0;
X		}
X	if (chdir(get_str(1)))
X		accumulator = 0;
X	else
X		accumulator = 1;
X	cwd[0] = NULL;
X	return 0;
X}
Xredraw()
X{
X	sgarbf = TRUE;
X	update();
X	return 0;
X}
Xtop_of_window()
X{
X	u_dot();
X	win_modify(WFMOVE);
X	curwp->w_line = curwp->w_top_line;
X	curwp->w_col = 1;
X	win_modify(WFMOVE);
X	return 0;
X}
Xend_of_window()
X{	int	line = curwp->w_line;
X
X	u_dot();
X	win_modify(WFMOVE);
X	curwp->w_line = curwp->w_top_line + curwp->w_h - 1;
X	if (curwp->w_line > curbp->b_numlines)
X		curwp->w_line = curbp->b_numlines;
X	accumulator = line != curwp->w_line;
X	win_modify(WFMOVE);
X	return 0;
X}
Xdo_getpid()
X{
X	accumulator = (long) getpid();
X	return 0;
X}
Xinq_system()
X{
X	accumulator = curbp->b_system;
X	return 0;
X}
X# include	<time.h>
Xchar	*days[] = {
X	"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
X	"Saturday"};
Xchar	*months[] = {
X	"January", "February", "March", "April", "May", "June", 
X	"July", "August", "September", "October", "November", "December"
X	};
X
Xextern long time();
Xdo_time()
X{	struct tm *tp;
X	long	l = time((long *) 0);
X
X	tp = localtime(&l);
X	if (argv[1].l_flags != F_NULL)
X		argv[1].l_sym->s_int = tp->tm_hour;
X	if (argv[2].l_flags != F_NULL)
X		argv[2].l_sym->s_int = tp->tm_min;
X	if (argv[3].l_flags != F_NULL)
X		argv[3].l_sym->s_int = tp->tm_sec;
X	return 0;
X}
Xdo_date()
X{	struct tm *tp;
X	long	l = time((long *) 0);
X
X	tp = localtime(&l);
X	
X	if (argv[1].l_flags != F_NULL)
X		argv[1].l_sym->s_int = tp->tm_year + 1900;
X	if (argv[2].l_flags != F_NULL)
X		argv[2].l_sym->s_int = tp->tm_mon+1;
X	if (argv[3].l_flags != F_NULL)
X		argv[3].l_sym->s_int = tp->tm_mday;
X	if (argv[4].l_flags != F_NULL)
X		str_assign(argv[4].l_sym, months[tp->tm_mon]);
X	if (argv[5].l_flags != F_NULL)
X		str_assign(argv[5].l_sym, days[tp->tm_wday]);
X	return 0;
X
X}
Xuse_tab_char()
X{	char	*cp;
X	char	buf[32];
X
X	accumulator = tab_char;
X	if ((cp = get_arg1("Fill with tab chars? ", buf, sizeof buf)) == NULL)
X		return 0;
X	tab_char = *cp == 'y' || *cp == 'Y';
X	return 0;
X}
Xinq_line_length()
X{	int	i, saved_line;
X	extern int start_line, end_line;
X	int	line_length = 0;
X	BUFFER	*bp = argv[1].l_flags == F_INT 
X			? numberb((u_int16) argv[1].l_int) 
X			: curbp;
X	BUFFER	*saved_curbp = curbp;
X
X	if (bp == NULL) {
X		accumulator = -1;
X		return;
X		}
X	curbp = bp;
X	set_hooked();
X	if (get_marked_areas((WINDOW *) NULL) == FALSE) {
X		start_line = 1;
X		end_line = curbp->b_numlines - 1;
X		}
X	saved_line = *cur_line;
X
X	for (i = start_line; i <= end_line; i++) {
X		int	len;
X		LINE	*lp = vm_lock_line(i);
X
X		*cur_line = i;
X		len = current_col(llength(lp));
X		if (len > line_length)
X			line_length = len;
X		}
X
X	accumulator = line_length;
X	curbp = saved_curbp;
X	set_hooked();
X	*cur_line = saved_line;
X	return;
X}
Xint sleep_finished;
Xstatic
Xdo_sleep_wakeup()
X{
X	sleep_finished = TRUE;
X}
Xdo_sleep()
X{	long	n = argv[1].l_flags == F_INT ? argv[1].l_int : 1;
X
X	if (n == 0)
X		return;
X	sleep_finished = FALSE;
X
X	clk_timeout(do_sleep_wakeup, 0, n SECONDS);
X	while (clock_check() && sleep_finished == FALSE) {
X		pause();
X		}
X
X}	
SHAR_EOF
chmod 0444 ./mac1.c || echo "restore of ./mac1.c fails"
mkdir . >/dev/null 2>&1
echo "x - extracting ./main.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ./main.c &&
X/**************************************************************
X *
X *	CRISP - Custom Reduced Instruction Set Programmers Editor
X *
X *	(C) Paul Fox, 1989
X *	43, Jerome Close	      Tel: +44 6284 4222
X *	    Marlow
X *	     Bucks.
X *		England SL7 1TX
X *
X *
X *    Please See COPYRIGHT notice.
X *
X **************************************************************/
X
X# define	MAIN
X
X#include        "list.h"
X# include	<signal.h>
X# ifndef	MALLOC
X# include	<malloc.h>
X# endif
X# include	"clk.h"
XSCCSID("@(#) main.c 1.16, (C) P. Fox");
X
Xvoid	usage();
Xextern	char	*strtok();
X
X# define	MAX_M	12	/* Number of -m switches		*/
X
Xextern	int	tab_char;
Xextern	int	echo_flags;
Xint	plus_line_number = 0;
Xint	display_enabled = FALSE;/* Set to TRUE when we do a (set_term_characters). */
Xchar	*m_strings[MAX_M];	/* Array of pointer to -m strings.	*/
Xint	m_cnt = 0;
Xint	ega43_flag = FALSE;	/* TRUE if in 43 line mode.		*/
Xint	m_flag = FALSE;		/* Set to TRUE whilst processing -m strings*/
X				/* to avoid messages being printed.	*/
Xint	b_level = 0;		/* Value of BLEVEL.			*/
Xstruct mac_stack mac_stack[MAX_NESTING] = {0};/* Macro name stack.		*/
Xint	ms_cnt;
Xint	msg_level = 0;
Xint	wait_flag = TRUE;		/* Set to FALSE if read_char should*/
X					/* return -1 on no key pressed.	*/
X					/* No macros currently use the  */
X					/* fact that read_char can return -1*/
Xint     thisflag;                       /* Flags, this command          */
Xint     lastflag;                       /* Flags, last command          */
XBUFFER  *curbp;                         /* Current buffer               */
XBUFFER	*scrap_bp;			/* Pointer to scrap buffer.	*/
XWINDOW  *curwp;                         /* Current window               */
XBUFFER  *bheadp = NULL;                 /* BUFFER listhead              */
XWINDOW  *wheadp = (WINDOW *)NULL;       /* WINDOW listhead              */
Xchar    pat[NPAT];                      /* Pattern                      */
Xint	flush_flag = FALSE;		/* TRUE if flush log file after */
X					/* every write.			*/
Xint	p_level = 0;
Xchar	*prog_name;
Xextern	long interval;
Xint	ref_flag = FALSE;		/* If TRUE, dump refs on exit.	*/
Xint	pflag = FALSE;			/* TRUE if profiling on.	*/
Xint	sflag = FALSE;			/* TRUE if stats reporting on exit.*/
Xextern char	*ggetenv();
Xint	dump_core = FALSE;
Xint	do_backups = TRUE;
Xint	ctrl_c = FALSE;			/* TRUE when SIGINT occured.	*/
Xstatic	doswitches();
X
Xint_signal()
X{
X	ctrl_c = TRUE;
X	signal(SIGINT, int_signal);
X}
Xmem_error()
X{	static int mem_error_level = 0;
X
X	ewprintf("");
X	if (mem_error_level++ == 0) {
X		signal(SIGSEGV, SIG_DFL);
X		signal(SIGBUS, SIG_DFL);
X		str_exec("_fatal_error");
X		}
X	printf("\r\nSEGMENTATION VIOLATION DETECTED.\n\r\n");
X	dump_core = TRUE;
X	gr_exit();
X}
Xmain(_argc, _argv) 
Xchar **_argv; 
X{
X	int	i;
X	int	arg_index;
X	int	bus_error();
X	extern int autoloading;
X	void	edinit();
X	void	init_register();
X	extern	reg_idle();
X
X	malloc_hack();
X	signal(SIGBUS, bus_error);
X	signal(SIGSEGV, bus_error);
X	signal(SIGIOT, bus_error);
X	signal(SIGINT, int_signal);
X
X	prog_name = _argv[0];
X
X	setup_env();
X
X	arg_index = doswitches(_argc, _argv);
X# ifdef	SUN
X	siginterrupt(SIGALRM, 1);
X# endif
X
X	init_builtin();
X	init_macros();
X	key_init();
X/*	vm_init();*/
X	u_init();				/* Undo buffer.		*/
X	vtinit();                               /* Virtual terminal.    */
X	edinit();                               /* Buffers, windows.    */
X	k_init();				/* Kill buffer.		*/
X	init_register();			/* Initialise register  */
X						/* macro array.		*/
X	/* doing update() before reading files causes the error messages from
X	 * the file I/O show up on the screen.  (and also an extra display
X	 * of the mode line if there are files specified on the command line.)
X	 */
X	update();
X	sym_init();
X	startupfile();
X	lastflag = 0;
X	p_level = 0;
X	for (i = 0; i < m_cnt; i++) {
X		autoloading = TRUE;
X		m_flag = TRUE;
X		ld_macro(m_strings[i]);
X		}
X
X	signal(SIGBUS, mem_error);
X	signal(SIGSEGV, mem_error);
X	signal(SIGIOT, SIG_DFL);
X	if (arg_index < _argc) {
X		BUFFER	*firstbp = NULL;
X
X		while (arg_index < _argc) {
X			atomic_fileedit(_argv[arg_index++]);
X			if (!firstbp)
X				firstbp = curbp;
X			}
X		showbuffer(curbp = firstbp, curwp);
X		}
X	else
X		atomic_fileedit(ggetenv("BFILE"));
X
X	p_level = 0;
X	for (i = 0; i < m_cnt; i++) {
X		m_flag = TRUE;
X		str_exec(m_strings[i]);
X		}
X	m_flag = autoloading = FALSE;
X	if (plus_line_number) {
X		set_hooked();
X		gotoline(plus_line_number);
X		}
X
X	if (interval)
X		clk_timeout(reg_idle, 0, interval SECONDS);
X	while (p_level >= 0) {
X		p_level = 0;
X		process();
X		check_exit();
X		}
X	gr_exit();
X}
Xsetup_env()
X{	char	*cp;
X	char buf[128];
X	extern	char	*bpath;
X	extern	char	*bhelp;
X
X	if (ggetenv("BPATH") == NULL) {
X		sprintf(buf, "BPATH=%s", bpath);
X		if (cp = ggetenv("HOME")) {
X			strcat(buf, ";");
X			strcat(buf, cp);
X			}
X		gputenv(buf);
X		}
X	else
X		bpath = ggetenv("BPATH");
X
X	if (ggetenv("BHELP") == NULL) {
X		sprintf(buf, "BHELP=%s", bhelp);
X		gputenv(buf);
X		}
X	if (ggetenv("BPACKAGES") == NULL) {
X		extern char *bpackages;
X		gputenv(bpackages);
X		}
X	if (ggetenv("BFLAGS") == NULL) {
X		extern char *bflags;
X		gputenv(bflags);
X		}
X	if (ggetenv("BFILE") == NULL) {
X		extern char *bfile;
X		gputenv(bfile);
X		}
X	if (cp = ggetenv("BFLAGS")) {
X		char	**cpp = &cp;
X		doswitches(-1, cpp);
X		}
X	if (cp = ggetenv("BLEVEL"))
X		b_level = atoi(cp) + 1;
X	else
X		b_level = 1;
X	sprintf(buf, "BLEVEL=%d", b_level);
X	gputenv(buf);
X}
Xcheck_exit()
X{
X	if (anycb() == FALSE)
X		gr_exit();
X}
Xgr_exit()
X{	extern int	imode;
X	void	_cleanup();
X	int	i, j;
X
X	if (!dump_core)
X		trigger(REG_EXIT);
X	if (ref_flag) {
X		extern int dflag;
X		dflag = 1;
X		trace_refs();
X		}
X	if (!imode)
X		ins_mode();
X	u_close();
X	vttidy();
X	
X	if (sflag) {
X		extern long st_charout;
X		printf("[Chars out: %ld]\n", st_charout);
X		printf("Symbol Table:\n");
X		printf("Globals:  %s\n", spstats(gsym_tbl));
X		printf("Locals:\n");
X		for (i = j = 0; i < MAX_NESTING && j < 3; i++) {
X			if (lsym_tbl[i]->lookups + lsym_tbl[i]->enqs + 
X				lsym_tbl[i]->splays == 0)
X				j++;
X			printf("  level %02d: %s\n", i, spstats(lsym_tbl[i]));
X			}
X		}
X
X	if (dump_core)
X		abort();
X	if (pflag)
X		exit(EXIT_SUCCESS);
X
X	_cleanup();
X	return _exit(EXIT_SUCCESS);
X}
Xprocess()
X{	KEY	c;
X	int	last_p_level;
X
X	p_level++;
X	while (1) {
X		update();
X		last_p_level = p_level;
X		c = getkey();
X		clock_check();
X		(void) exec_key(c);
X		if (p_level < last_p_level)
X			return 0;
X		lastflag = thisflag;
X		thisflag = 0;
X		}
X}
X/*
X * Initialize all of the buffers
X * and windows. The buffer name is passed down as
X * an argument, because the main routine may have been
X * told to read in a file by default, and we want the
X * buffer name to be right.
X */
Xvoid
Xedinit()
X{
X	register BUFFER *bp;
X	register WINDOW *wp;
X	extern	u_int16	win_num;
X	extern WINDOW *new_window();
X
X	bheadp = NULL;
X	scrap_bp = bp = bfind("/-scrap-/", TRUE);
X	scrap_bp->b_flag |= BFREAD;
X	scrap_bp->b_system = 0;
X
X	wp = new_window();
X
X	if (bp==NULL || wp==NULL) panic("edinit");
X	curbp  = bp;                            /* Current ones.        */
X	bp->b_nwnd  = 1;                        /* Displayed.           */
X	bp->b_keyboard = NULL;
X	wheadp = wp;
X	curwp  = wp;
X	wp->w_bufp  = bp;
X	wp->w_top_line = wp->w_line = wp->w_col = 1;
X	wp->w_popup = FALSE;
X
X	wp->w_h = nrow-2;
X	wp->w_tiled = W_ROOT;
X	cur_line = &bp->b_line;
X	cur_col = &bp->b_col;
X
X	if (wp->w_tiled) {
X		wp->w_x = 1;
X		wp->w_w = ncol - 2;
X		wp->w_h--;
X		}
X	else {
X		wp->w_w = ncol;
X		}
X	wp->w_num = win_num++;
X	wp->w_flag  = WFHARD;            /* Full.                */
X	w_title(wp, "*scratch*", "");
X}
Xdo_exit()
X{
X	p_level--;
X	return 0;
X}
Xstatic
Xdoswitches(_argc, _argv)
Xchar	**_argv;
X
X{	int	c;
X	char *optarg;
X	extern char *strchr();
X	extern int dflag;
X	int	errflag = 0;
X	int optind;
X	char	*av[16];
X	char	*cp;
X	static char	buf[128];
X	extern int rem_size;
X
X	if (_argc < 0) {
X		strncpy(buf, *_argv, sizeof buf - 1);
X		_argc = 1;
X		for (cp = strtok(buf, " "); cp; cp = strtok((char *) NULL, " "))
X			av[_argc++] = cp;
X		_argv = av;
X		}
X	for (optind = 1; optind < _argc; optind++) {
X		cp = _argv[optind];
X		if (*cp == '+') {
X			plus_line_number = atoi(cp+1);
X			continue;
X			}
X		if (*cp++ != '-')
X			break;
X		while (c = *cp++) {
X			if (strchr("eKiMm", c)) {
X				if (*cp == NULL && (optind+1) >= _argc)
X					usage();
X				if (*cp) {
X					optarg = cp;
X					cp = "";
X					}
X				else
X					optarg = _argv[++optind];
X				}
X			switch (c) {
X				case 'b': do_backups = FALSE; break;
X				case 'd': dflag = TRUE; break;
X				case 'E': display_enabled = TRUE; break;
X				case '4': ega43_flag = TRUE; break;
X				case 'e':
X					echo_flags = atoi(optarg);
X					break;
X				case 'f': flush_flag = TRUE; break;
X				case 'i':
X					interval = atoi(optarg);
X					break;
X				case 'K':
X					rem_size = atoi(optarg);
X					break;
X				case 'M': {
X/*					extern long vm_maxlines;
X					vm_maxlines = atoi(optarg);*/
X					break;
X					}
X					
X				case 'm':
X					if (m_cnt >= MAX_M-1)
X						break;
X					m_strings[m_cnt++] = optarg;
X					break;
X		
X				case 'p':	pflag = TRUE; break;
X				case 'r':	ref_flag = TRUE; break;
X				case 's':	sflag = TRUE; break;
X				case 't':	tab_char = FALSE; break;	
X				case 'w':	wait_flag = FALSE; break;
X				default:
X					errflag++;
X				}
X			}
X		}
X	if (errflag)
X		usage();
X	return optind;
X}
Xvoid
Xusage()
X{
X	fprintf(stderr, "Usage: %s [+nn] [-4bdifpstwE] [-e n] [-K nn] [-m macro] [-M n] file ..\n", prog_name);
X	fprintf(stderr, "\n");
X	fprintf(stderr, "	+nn	Goto line nn.\n");
X	fprintf(stderr, "	-4	43-line mode EGA (Xenix only)\n");
X	fprintf(stderr, "	-b	Don't create backups.\n");
X	fprintf(stderr, "	-E	Enable display on startup.\n");
X	fprintf(stderr, "	-d	Create crisp.log error log.\n");
X	fprintf(stderr, "	-e nn	Set echo line state flag.\n");
X	fprintf(stderr, "	-f	Flush log file as created.\n");
X	fprintf(stderr, "	-K nn	Set keyboard macro size to nn.\n");
X	fprintf(stderr, "	-iN	Set interval timer to N seconds\n");
X	fprintf(stderr, "	-M n	Set virtual memory size to n lines\n");
X	fprintf(stderr, "	-m str	Execute macro 'str'.\n");
X	fprintf(stderr, "	-p	Turn profiling on.\n");
X	fprintf(stderr, "	-r	Dump macro ref statistics.\n");
X	fprintf(stderr, "	-s	Report statistics on exit.\n");
X	fprintf(stderr, "	-t	Use spaces to fill out tabs\n");
X	fprintf(stderr, "	-w	Allow read_char to return -1.\n");
X	exit(EXIT_FAILURE);
X}
Xbus_error()
X{
X	vttidy();
X	fprintf(stderr, 
X"\n\nA program error (segmentation error) occured during startup.\n");
X	return gr_exit();
X}
Xenable_display()
X{
X	display_enabled = argv[1].l_flags == F_INT ?
X		argv[1].l_int : !display_enabled;
X	char_width_init();
X}
SHAR_EOF
chmod 0444 ./main.c || echo "restore of ./main.c fails"
mkdir . >/dev/null 2>&1
echo "x - extracting ./map.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ./map.c &&
X/**************************************************************
X *
X *	CRISP - Custom Reduced Instruction Set Programmers Editor
X *
X *	(C) Paul Fox, 1989
X *	43, Jerome Close	      Tel: +44 6284 4222
X *	    Marlow
X *	     Bucks.
X *		England SL7 1TX
X *
X *
X *    Please See COPYRIGHT notice.
X *
X **************************************************************/
X/*------------------------------------------------------
X *    File containing various mapping functions.
X *------------------------------------------------------*/
X# include	"list.h"
X
XSCCSID("@(#) map.c 1.10, (C) P. Fox");
X
Xint	virtual_space = FALSE;
XLINE	*global_lp;
X
X/* Code to return width of a character on display. */
X
Xchar	char_width_tbl[256];
Xchar	*ctrl_chars[] = {
X	"^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H",
X	"^I", "^J", "^K", "^L", "^M", "^N", "^O", "^P", "^Q",
X	"^R", "^S", "^T", "^U", "^V", "^W", "^X", "^Y", "^Z",
X	"^[", "^\\", "^]", "^^", "^_"
X	};
Xint	ctrl_size;
Xchar_width_init()
X{	register char *cp = char_width_tbl;
X	register int i;
X
X# define	NUM_CTRLS	32
X	for (i = 0; i < NUM_CTRLS; i++)
X		*cp++ = pt.pt_character[0] == NULL ? strlen(ctrl_chars[i]) : 1;
X# define	NUM_PRINTABLE	(0x7F - 0x20)
X	for (i = NUM_PRINTABLE; i-- > 0; )
X		*cp++ = 1;
X# define	NUM_TOPBIT	(0x80 + 1)
X	for (i = NUM_TOPBIT; i-- > 0; )
X		*cp++ = pt.pt_character[0] == NULL ? 4 : 1;
X
X	/*----------------------------------
X	/*   Characters used for window 
X	/*   borders must be 1 character wide.
X	/*----------------------------------*/
X	for (i = CH_MIN; i <= CH_MAX; i++)
X		char_width_tbl[i] = 1;
X}
X/*# define	char_width(pos, ch)  (ch == '\t' \
X					? (next_tab_stop(pos) + 1 - pos) \
X					: char_width_tbl[ch])*/
Xextern char _chars_[256];
Xstatic int _x_;
X# define char_width(pos, offset, cpp) \
X		(_chars_[_x_ = **cpp] & 0x10 ? char_width1(pos, offset, cpp) : \
X		((*cpp)++, (*offset)--,	char_width_tbl[_x_]))
X
Xchar_width1(pos, offset, cpp)
Xregister unsigned char **cpp;
Xint	*offset;
X{
X	int ch = **cpp;
X	register int	off = *offset;
X	register unsigned char *cp;
X		
X	if (ch == '\t') {
X		(*cpp)++;
X		(*offset)--;
X		return next_tab_stop(pos) + 1 - pos;
X		}
X	if ((curbp->b_flag & BFANSI) == 0) {
X		(*cpp)++;
X		(*offset)--;
X		return char_width_tbl[0x1b];
X		}
X	for (cp = *cpp; off-- >= 0 && !isalpha(*cp); cp++)
X		;
X	if (off < 0 || *cp != 'm') {
X		(*cpp)++;
X		(*offset)--;
X		return char_width_tbl[0x1b];
X		}
X	*offset = off;
X	*cpp = cp+1;
X	return 0;
X}
Xint base_flag = 0;
Xdisplay_mode()
X{
X	accumulator = base_flag;
X	if (argv[1].l_flags == F_INT) {
X		base_flag = argv[1].l_int;
X		char_width_init();
X		}
X}
X
X
X/************************************************************************
X *                                                                      *
X *				linep                                   *
X *				-----                                   *
X *                                                                      *
X *  Purpose:                                                            *
X *                                                                      *
X *     Take a line number and return a pointer to the line header.      *
X *     Does optimisations to avoid travelling around the ring.          *
X ************************************************************************/
X
XLINE	*
Xlinep(line)
Xregister int line;
X{	register int diff;
X	register LINE *lp;
X	int cline;
X
X	if ((cline = curbp->b_cline) == line)
X		return curbp->b_clinep;
X	if (cline > line) {
X		diff = cline - line;
X		if (diff < line) {
X			lp = curbp->b_clinep;
Xgo_back:
X			while (diff-- > 0)
X				lp = lback(lp);
X			curbp->b_cline = line;
X			curbp->b_clinep = lp;
X			return lp;
X			}
X		diff = line - 1;
X		lp = lforw(curbp->b_linep);
X		}
X	else {
X		diff = curbp->b_numlines - line;
X		if (diff < line - cline) {
X			lp = curbp->b_linep;
X			goto go_back;
X			}
X		diff = line - cline;
X		lp = curbp->b_clinep;
X		}
X	while (diff-- > 0)
X		lp = lforw(lp);
X	curbp->b_clinep = lp;
X	curbp->b_cline = line;
X	return lp;
X}
Xflush_cache(bp)
XBUFFER	*bp;
X{
X	bp->b_clinep = lforw(bp->b_linep);
X	bp->b_cline = 1;
X}
X
X/************************************************************************
X *                                                                      *
X *				current_col                             *
X *				-----------                             *
X *                                                                      *
X *  Purpose:                                                            *
X *                                                                      *
X *     Convert the current column position into an absolute position    *
X *     offset to the current line.                                      *
X *----------------------------------------------------------------------*
X *  Input Parameters:                                                   *
X *----------------------------------------------------------------------*
X *  Output:                                                             *
X *----------------------------------------------------------------------*
X *  Global variables modified:                                          *
X ************************************************************************/
SHAR_EOF
echo "End of part 7"
echo "File ./map.c is continued in part 8"
echo "8" > s2_seq_.tmp
exit 0
-- 
=====================			Reuters Ltd PLC, 
Tel: +44 628 891313 x. 212		 Westthorpe House,
UUCP:     fox%marlow.uucp@idec.stc.co.uk  Little Marlow,
					   Bucks, England SL7 3RQ