[comp.sources.misc] v07i046: CRISP release 1.9 part 25/32

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

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



#!/bin/sh
# this is part 5 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file ./echo.c continued
#
CurArch=5
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 ./echo.c"
sed 's/^X//' << 'SHAR_EOF' >> ./echo.c
X       pos += printable_char(buf[i]);
X/* recalculate left    */
X   if (startcol + pos - *left >= LCOL-1 || pos < *left) {
X       if (pos < *left)
X           *left = pos;
X       else
X           *left = startcol + pos - LCOL + 1;
X/* re-adjust left for ctl characters   */
X       for (i = n = 0; i < *left; i += printable_char(buf[n++]))
X           ;
X       *left = i;
X/* reprint the line    */
X       ecol = startcol;
X       ttmove(nrow - 1, startcol);
X       while (ecol < LCOL-1 && buf[n])
X           eputc1(buf[n++]);
X       echo_line[ecol] = NULL;
X       }
X   ttmove(nrow - 1, startcol + pos - *left);
X   ecol = startcol + pos - *left;
X   ttflush();
X   return pos;
X}
X
X
X/*
X *  eclear()
X *     clear up to four spaces after input line to clear crud left over
X *     from deleting or overtyping ctl characters.
X */
X
Xvoid
Xeclear()
X{
X   int i;
X   int	space = FG(col_table.c_messages) | ' ';
X
X   for (i = ecol; i < ecol + 4  &&  i < LCOL - 1; i++)
X       ttputc(space);
X}
Xestrlen(str)
Xregister char *str;
X{	register int	len = 0;
X
X	while (*str) {
X		char ch = *str++;
X		len += printable_char(ch >= ' ' ? ch : (ch | 0x80));
X		}
X	return len;
X
X}
Xinq_message()
X{
X	strl_acc_assign(echo_line);
X}
Xinq_cmd_line()
X{
X	strl_acc_assign(echo_line + prompt_len);
X}
X/*
X * Special "printf" for the echo line.
X * Each call to "ewprintf" starts a new line in the
X * echo area, and ends with an erase to end of the
X * echo line. The formatting is done by a call
X * to the standard formatting routine.
X */
X/* VARARGS1 */
Xvoid
Xewprintf(str, ARG_LIST)
Xchar	*str;
X{	unsigned char	buf[EBUFSIZ];
X
X	sprintf(buf, str, ARG_LIST);
X	ewputs(buf, (char *) NULL);
X}
X/* VARARGS1 */
Xvoid
Xewputs(str, defstr)
Xchar	*str;
Xchar	*defstr;
X{	int	len;
X	register char *cp;
X
X	epresf = TRUE;
X
X	ttmove(nrow-1, 0);
X/*	set_attr(0);*/
X/*	ttcolor(pcolor);*/
X	strncpy(echo_line, str, LCOL-1);
X	echo_line[LCOL-1] = NULL;
X	ecol = 0;
X
X	for (cp = str; *cp; )
X		eputc1(*cp++);
X	len = estrlen(echo_line);
X
X	if (defstr && *defstr) {
X		int color = FG(col_table.c_fg) | BG(col_table.c_bg);
X		strcat(echo_line, defstr);
X		for (cp = defstr; *cp && ecol < LCOL - 1; cp++)
X			eputc((*cp < ' ' ? (*cp + 0x80) : *cp) | color);
X		len += estrlen(defstr);
X		}
X	ttspace(LCOL - len, ' ' | FG(col_table.c_normal), TRUE);
X	echo_line[ecol] = NULL;
X	ttflush();
X
X}
Xeputc1(c)
X{
X	int	color = pcolor == CMESSAGE ? col_table.c_messages : col_table.c_error;
X	color = FG(color);
X	if (c < ' ')
X		c += 0x80;	
X	eputc(c | color);
X}
Xvoid
Xeputc(c)
Xint	c;
X{	int	low_byte = c & 0xff;
X	int	hi_byte = c & 0xff00;
X	register int	*cp;
X	extern int pchar_buf[];
X	register int	i;
X
X	trace_log("%c", c);
X	if (c == '\r' || c == '\n')
X		return;
X
X
X	i = printable_char(c);
X	for (cp = pchar_buf; i-- > 0 && ecol < LCOL - 1; ) {
X		int	ch = *cp++ | hi_byte;
X		ttputc(ch);
X		echo_line[ecol++] = ch;
X		}
X}
Xvoid
Xeerase()
X{
X	epresf = FALSE;
X	echo_line[0] = NULL;
X	ttmove(nrow-1, 0);
X/*	set_attr(0);*/
X	ttspace(LCOL, ' ' | FG(col_table.c_normal), TRUE);
X	ttflush();
X	ecol = 0;
X}
Xvoid
Xline_col(force)
X{
X	char	buf[40];
X	struct tm *tp;
X	extern long time();
X	long	timl;
X	static	int	hours = -1;
X	static	int	minutes = -1;
X	static int	old_line = -1;
X	static int	old_col = -1;
X	static long	old_perc = 1;
X	static char	xx[3];
X	static	char	*old_rem_string = xx;
X	extern	int	imode;
X	extern char *rem_string;
X	int	l = curwp->w_line;
X	int	c = curwp->w_col;
X	int	old_color;
X	long	perc;
X# define	LINE_POS	LCOL
X# define	COL_POS		(LCOL+11)
X# define	TIME_POS	(COL_POS + 11)
X# define	REMEMBER_POS	(TIME_POS - 3)
X# define	CURSOR_POS	(REMEMBER_POS)
X
X	if (force) {
X		old_perc = old_col = old_line = hours = minutes = -1;
X		old_rem_string = xx;
X		}
X	timl = time((long *) 0);
X	tp = localtime(&timl);
X	if (c == old_col && l == old_line &&
X		tp->tm_hour == hours && tp->tm_min == minutes &&
X		*rem_string == *old_rem_string)
X		return;
X
X/*	set_attr(0);*/
X	if (force) {
X		ttmove(nrow-1, LINE_POS);
X		tteeol();
X		}
X	if (echo_flags & E_LINE && l != old_line) {
X		if (force) {
X			ttmove(nrow-1, LINE_POS);
X			sprintf(buf, "Line: %-5u", l);
X			}
X		else {
X			ttmove(nrow-1, LINE_POS+6);
X			sprintf(buf, "%-5u", l);
X			}
X		ttputs_color(buf, col_table.c_normal);
X		}
X	if (echo_flags & E_COL && c != old_col) {
X		if (force) {
X			ttmove(nrow-1, COL_POS);
X			sprintf(buf, "Col: %-3u", c);
X			}
X		else {
X			ttmove(nrow-1, COL_POS+5);
X			sprintf(buf, "%-3u", c);
X			}
X		ttputs_color(buf, col_table.c_normal);
X		}
X	if (echo_flags & E_CURSOR && pt.pt_icursor[0] == NULL) {
X		ttmove(nrow-1, CURSOR_POS);
X		ttputs_color(imode ? "IN" : "OV", col_table.c_normal);
X		}
X	perc = (l * 100) / curbp->b_numlines;
X	if (perc > 100)
X		perc = 100;
X	if (echo_flags & E_PERCENT && perc != old_perc) {
X		ttmove(nrow-1, CURSOR_POS);
X		if (perc >= 100)
X			strcpy(buf, "END ");
X		else
X			sprintf(buf, "%2lu%%", perc);
X		ttputs_color(buf, col_table.c_normal);
X		}
X	if (echo_flags & E_REMEMBER && *rem_string != *old_rem_string) {
X		ttmove(nrow-1, REMEMBER_POS);
X		ttputs_color(rem_string, col_table.c_normal);
X		}
X
X	if (echo_flags & E_TIME &&
X		(tp->tm_hour != hours || tp->tm_min != minutes)) {
X		extern char *MB, *ME;
X		ttmove(nrow-1, TIME_POS);
X		sprintf(buf, "%2d",
X			tp->tm_hour > 12 ? tp->tm_hour - 12 :
X			tp->tm_hour == 0 ? 12 : tp->tm_hour);
X		if (MB && ME)
X			sprintf(buf+strlen(buf), "%s:%s", MB, ME);
X		else
X			strcat(buf, ":");
X		ttputs_color(buf, col_table.c_normal);
X		buf[0] = NULL;
X		flush_col_cache();
X		sprintf(buf, "%02d %cm",
X			tp->tm_min, tp->tm_hour >= 12 ? 'p' : 'a');
X		ttputs_color(buf, col_table.c_normal);
X		hours = tp->tm_hour;
X		minutes = tp->tm_min;
X		}
X
X	ttflush();
X
X	old_line = l;
X	old_col = c;
X	old_perc = perc;
X	strcpy(old_rem_string, rem_string);
X}
Xttputs_color(buf, color)
Xchar *buf;
X{	
X	color = FG(color);
X	while (*buf)
X		ttputc(*buf++ | color);
X}
Xset_echo_line()
X{
X	accumulator = echo_flags;
X	if (argv[1].l_flags != F_NULL) {
X		echo_flags = argv[1].l_int;
X		line_col(TRUE);
X		}
X	return 0;
X}
SHAR_EOF
echo "File ./echo.c is complete"
chmod 0444 ./echo.c || echo "restore of ./echo.c fails"
mkdir . >/dev/null 2>&1
echo "x - extracting ./env.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ./env.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 *   Code to allow us to implement getenv() and putenv() in
X *   a way that is portable to VMS which doesnt have putenv()
X *   on our system.
X *
X **************************************************************/
X# include	"list.h"
X
XSCCSID("@(#) env.c 1.3, (C) 1989, P. Fox");
X# if !defined(VMS)
Xchar	*
Xggetenv(name)
Xchar *name;
X{	char *getenv();
X	return getenv(name);
X}
Xgputenv(name)
Xchar *name;
X{
X	char *strdup();
X	return putenv(strdup(name));
X}
X# else
Xstatic	Head_p	hd_env = NULL;
X
Xstatic List_p	glookup();
X
Xchar	*
Xggetenv(name)
Xchar	*name;
X{	List_p lp = glookup(name);
X	char *cp;
X
X	if (lp == NULL)
X		return getenv(name);
X	for (cp = (char *) ll_elem(lp); *cp != '=' && *cp; )
X		cp++;
X	return *cp == '=' ? cp + 1 : cp;
X}
Xgputenv(name)
Xchar	*name;
X{	char *cp = strdup(name);
X	List_p	lp;
X	
X	if ((lp = glookup(name)) != NULL) {
X		chk_free((char *) ll_elem(lp));
X		ll_delete(lp);
X		}
X	ll_append(hd_env, cp);
X}
Xstatic List_p
Xglookup(name)
Xchar *name;
X{	int	len;
X	List_p	lp;
X	
X	if (hd_env == NULL) {
X		hd_env = ll_init();
X		return NULL;
X		}
X		
X	for (len = 0; name[len] != '=' && name[len]; )
X		len++;
X		
X	for (lp = ll_first(hd_env); lp; lp = ll_next(lp)) {
X		char *lname = (char *) ll_elem(lp);
X		if (strncmp(name, lname, len) == 0 &&
X		    lname[len] == '=')
X			return lp;
X		}
X	return NULL;
X}
X# endif
SHAR_EOF
chmod 0444 ./env.c || echo "restore of ./env.c fails"
mkdir . >/dev/null 2>&1
echo "x - extracting ./eval.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ./eval.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
XSCCSID("@(#) eval.c 1.6, (C) 1989 P. Fox");
X
Xeval(lp, lpv)
Xregister LIST	*lp;
Xregister LISTV	*lpv;
X{	extern SYMBOL *sym_lookup();
X
X	if (*lp == F_LIT) {
X		lpv->l_str = (char *) LGET32(lp);
X		lpv->l_flags = F_STR;
X		strl_acc_assign(lpv->l_str);
X		return F_LIT;
X		}
X	if (*lp == F_ID) {
X		lpv->l_str = builtin[LGET16(lp)].name;
X		lpv->l_flags = F_STR;
X		strl_acc_assign(lpv->l_str);
X		return F_LIT;
X		}
X	lpv->l_flags = *lp;
X	acc_type = F_INT;
X	if (*lp == F_STR) {
X		SYMBOL	*sp;
X		char *str = (char *) LGET32(lp);
X		if (strcmp(str, "NULL") == 0)
X			return lpv->l_flags = F_NULL;
X		if ((sp = sym_lookup(str)) == NULL) {
X			MACRO *mptr = lookup_macro(str);
X			if (mptr == NULL) {
X				ewprintf("Undefined symbol: %s", str);
X				return acc_type = F_ERROR;
X				}
X			trace_log("CODE<%s>\n", str);
X			acc_type = lpv->l_flags = F_LIST;
X			lpv->l_list = mptr->m_list;
X			return F_LIST;
X			}
X		trace_ilog("  lookup %s -> ", str);
X		acc_type = sp->s_type;
X		if (acc_type == F_STR) {
X			lpv->l_flags = F_RSTR;
X			lpv->l_rstr = sp->s_str;
X			trace_log("\"%s\"\n", c_string(sp->s_str->r_str));
X			return acc_type = F_RSTR;
X			}
X		if (acc_type == F_INT) {
X			lpv->l_flags = F_INT;
X			accumulator = lpv->l_int = sp->s_int;
X			trace_log("%ld\n", sp->s_int);
X			}
X		else {
X			lpv->l_flags = F_LIST;
X			lpv->l_list = sp->s_list;
X			trace_list(lpv->l_list);
X			}
X		return acc_type;
X		}
X	if (*lp == F_INT) {
X		accumulator = lpv->l_int = LGET32(lp);
X		return F_INT;
X		}
X	if (*lp != F_LIST)
X		return acc_type = F_ERROR;
X	execute_macro(lp + sizeof_atoms[F_LIST]);
X	if (acc_type == F_INT)
X		lpv->l_int = accumulator;
X	else if (acc_type == F_STR)
X		lpv->l_str = saccumulator;
X	else
X		lpv->l_list = (LIST *) saccumulator;
X	return lpv->l_flags = acc_type;
X}
Xchar *
Xget_str(n)
X{	register LISTV *lp = &argv[n];
X
X	if (lp->l_flags == F_STR || lp->l_flags == F_LIT)
X		return lp->l_str;
X	if (lp->l_flags == F_RSTR)
X		return lp->l_rstr->r_str;
X	if (lp->l_flags == F_INT || lp->l_flags == F_NULL)
X		return "";
X	if (lp->l_flags == F_LIST)
X		return (char *) lp->l_list;
X	panic("get_str");
X	/* NOTREACHED */
X}
Xget_len(n)
X{	register LISTV *lp = &argv[n];
X
X	if (lp->l_flags == F_STR || lp->l_flags == F_LIT)
X		return strlen(lp->l_str);
X	if (lp->l_flags == F_RSTR)
X		return lp->l_rstr->r_used;
X	if (lp->l_flags == F_INT || lp->l_flags == F_NULL)
X		return 0;
X	panic("get_len");
X	/* NOTREACHED */
X}
SHAR_EOF
chmod 0444 ./eval.c || echo "restore of ./eval.c fails"
mkdir . >/dev/null 2>&1
echo "x - extracting ./file.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ./file.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# include	"list.h"
X# include	"gdir.h"
X
XSCCSID("@(#) file.c 1.15, (C) 1989, P. Fox");
X
X
Xstatic DIR	*dirp = NULL;	/* Used by find_file & file_pattern */
Xstatic	char	file_buf[DIRSIZ+1];	/* Pattern to match.	*/
Xstatic	char	dir_buf[128];		/* Directory name for above. */
X
X
Xint	stat();
Xchar *filename();
Xvoid	percentage();
XBUFFER  *findbuffer();
Xextern	int	do_backups;
X
Xoutput_file()
X{	WINDOW	*wp;
X	char	buf[BUFSIZ];
X	char	*cp = get_arg1("Enter new output file name: ", buf, sizeof buf);
X	extern char	*filename();
X	extern char	*bname();
X	char	*fname;
X
X	if (cp == NULL)
X		return;
X	fname = filename(cp);
X
X	for (wp = wheadp; wp; wp = wp->w_wndp)
X		if (wp->w_bufp != curbp &&
X			strcmp(wp->w_bufp->b_fname, fname) == 0) {
X			errorf("Invalid output file name.");
X			return;
X			}
X	strncpy(curbp->b_fname, fname, sizeof curbp->b_fname-1);
X	for (wp = wheadp; wp; wp = wp->w_wndp)
X		if (wp->w_bufp == curbp) {
X			w_title(wp, bname(fname), "");
X			wp->w_flag |= WFHARD;
X			}
X	update();
X}
Xread_file()
X{	char	buf[BUFSIZ];
X	char	*cp = get_arg1("File to read: ", buf, sizeof buf);
X	int	perms_mode = curbp->b_mode;
X	int	read_only = curbp->b_flag & BFRO;
X	extern char **shell_expand();
X	char **files;
X	int	j;
X
X	accumulator = 0;
X
X	if (cp == NULL || rdonly())
X		return;
X	if ((files = shell_expand(cp)) == NULL) {
X		errorf("Name expansion error.");
X		return;
X		}
X	for (j = 0; files[j]; j++) {
X		if (files[j][0])
X			accumulator = insertfile(curbp, filename(files[j]), FALSE);
X		chk_free(files[j]);
X		}
X	chk_free(files);
X	curbp->b_mode = perms_mode;
X	curbp->b_flag &= ~BFRO;
X	curbp->b_flag |= read_only;
X}
X/*
X * given a file name, either find the buffer it uses, or create a new
X * empty buffer to put it in.
X */
XBUFFER *
Xfindbuffer(fname, s) 
Xchar *fname; 
Xint *s; 
X{
X	register BUFFER *bp;
X
X	for (bp=bheadp; bp!=NULL; bp=bp->b_bufp) {
X		if (strcmp(bp->b_fname, fname) == 0) {
X			return bp;
X		}
X	}
X	while ((bp=bfind(fname, FALSE)) != NULL) {
X		*s = ereply("Buffer name: ", fname, NBUFN);
X		if (*s == ABORT)
X			return NULL;
X		if (*s == FALSE) {
X			bp->b_fname[0] = '\0';
X			break;
X		}
X	}
X	if (bp == NULL) bp = bfind(fname, TRUE);
X	*s = FALSE;
X	return bp;
X}
X
Xreadin(bp, fname)
XBUFFER	*bp;
Xchar *fname; 
X{
X	register int            status;
X	register WINDOW         *wp;
X
X	if (bclear(bp) != TRUE)
X		return TRUE;
X	status = insertfile(bp, fname, TRUE);
X	bp->b_flag &= ~BFCHG;
X	bp->b_flag |= BFREAD;
X	if (status == 0)
X		bp->b_flag |= BFBAK;
X	for (wp = wheadp; wp; wp = wp->w_wndp) {
X		if (wp->w_bufp == bp) {
X			wp->w_top_line = 1;
X			wp->w_line  = 1;
X			wp->w_col  = 1;
X			}
X		}
X	return status;
X}
Xinsertfile(bp, fname, inserting)
XBUFFER	*bp;
Xchar fname[];
X{
X	register WINDOW *wp;
X	BUFFER          *saved_bp = curbp;
X	struct stat sbuf;
X	extern long	tell();
X	int	nline;
X	int	fd;
X
X	bp->b_mode = 0666;			/* Default mode for new files*/
X
X	if ((fd = open(fname, O_RDONLY)) < 0) {
X		if (curbp->b_system == 0) {
X			extern int errno;
X			extern int sys_nerr;
X			extern char *sys_errlist[];
X			if (inserting)
X				infof("New file (unable to open %s).", bname(fname));
X			else
X				infof("%s.", (errno < 0 || errno >= sys_nerr) ?
X					"Unknown error" : sys_errlist[errno]);
X			}			
X		return -1;
X		}
X	stat(fname, &sbuf);
X	bp->b_mode = sbuf.st_mode;
X	if (sbuf.st_mode & S_IEXEC)
X		bp->b_flag |= BFEXEC;
X	
X	curbp = bp;
X	set_hooked();
X	nline = lreadin_file(fd, sbuf.st_size, fname);
X# if 0	
X	nline = 1, n = 0;
X	while (1) {
X		int	j;
X		if ((n = read(fd, line, sizeof line - 1)) <= 0)
X			break;
X		pos += n;
X		if (pos == sbuf.st_size)
X			if (line[n-1] == '\n' && --n == 0)
X				break;
X		line[n] = NULL;
X		if ((j = linsert(line, n)) < 0)
X			break;
X		nline += j;
X		if (curbp->b_system == 0)
X			percentage(tell(fd), sbuf.st_size, "Reading", fname);
X		}
X# endif
X	close(fd);                       /* Ignore errors.       */
X	if (curbp->b_system != 1) {
X		if (nline == 1)
X			infof("[%s: 1 line.]", fname);
X		else
X			infof("[%s: %d lines.]", fname, nline);
X		}
X
X	if ((sbuf.st_mode & S_IWRITE) == 0)
X		bp->b_flag |= BFRO;
X	bp->b_flag |= BFCHG;
X
X	for (wp=wheadp; wp!=NULL; wp=wp->w_wndp)
X		if (wp->w_bufp == curbp)
X			wp->w_flag |= WFHARD;
X	curbp = saved_bp;
X	return 0;
X}
Xchar	*
Xbname(name)
Xchar	*name;
X{
X	extern	char	*strrchr();
X	char	*cp1 = strrchr(name, '/');
X	if (cp1)
X		return cp1+1;
X# if	defined(VMS)
X	if ((cp1 = strrchr(name, ']')) != NULL)
X		return cp1+1;
X	if ((cp1 = strrchr(name, ':')) != NULL)
X		return cp1+1;
X# endif
X	return name;
X}
X
X/*
X * Save the contents of the current buffer back into
X * its associated file. Do nothing if there have been no changes
X * (is this a bug, or a feature). Error if there is no remembered
X * file name. If this is the first write since the read or visit,
X * then a backup copy of the file is made.
X */
Xfilesave() 
X{	char	*fnam = argv[1].l_flags == F_NULL 
X			? curbp->b_fname : get_str(1);
X	int	append = argv[2].l_flags == F_INT ? argv[2].l_int : 0;
X	register int    s;
X
X	if (rdonly())
X		return TRUE;
X
X	if (argv[1].l_flags == NULL && curbp->b_anchor)
X		return write_block();
X
X	/*----------------------------------------
X	 *   Dont save file if its a normal buffer
X	 *   and there arent any changes; if its
X	 *   a system buffer save it anyway, because
X	 *   we dont keep track of 'b_nummod' for
X	 *   system buffers.
X	 *----------------------------------------*/
X	if (curbp->b_nummod == 0 && !curbp->b_system) {
X		infof("File has not been modified -- not written.");
X		return (TRUE);
X		}
X	if (*fnam == NULL) {
X		infof("No file name");
X		return FALSE;
X	}
X# if !defined(VMS)
X	if (argv[1].l_flags == F_NULL && do_backups && curbp->b_flag & BFBAK) {
X		s = fbackupfile(curbp->b_fname, curbp->b_mode);
X		if (s == FALSE                  /* Softer error.        */
X		&& (s=eyesno("Backup error, save anyway")) != TRUE)
X			return (s);
X		}
X# endif
X	if ((s=writeout(curbp, fnam, argv[1].l_flags == F_NULL, append)) == TRUE) {
X		if (argv[1].l_flags == F_NULL) {
X			curbp->b_flag &= ~(BFCHG | BFBAK);
X			curbp->b_nummod = 0;
X			}
X		}
X	return (s);
X}
X
X/*
X * This function performs the details of file
X * writing; writing the file in buffer bp to
X * file fn. Uses the file management routines
X * in the "fileio.c" package. Most of the crisp
X * is checking of some sort.
X */
Xwriteout(bp, fn, undo_term, append) 
Xregister BUFFER *bp; 
Xchar *fn; 
X{
X	register LINE   *lp;
X	FILE	*fp;
X	long	nlines = bp->b_numlines;
X	long	line;
X	BUFFER	*saved_bp = curbp;
X
X	if ((fp = fopen(fn, append ? "a" : "w")) == NULL) {
X		errorf("Cannot open file for writing");
X		return FALSE;
X		}
X
X	infof("Writing ...");
X	curbp = bp;
X	lp = linep(1);
X	for (line = 1; line < bp->b_numlines; line++) {
X		if (llength(lp)) {
X			if (fwrite(ltext(lp), llength(lp), 1, fp) != 1) {
X				errorf("File I/O error");
X				(void) fclose(fp);
X				return FALSE;
X				}
X			}
X		putc('\n', fp);
X		percentage(line, nlines, "Writing", bp->b_fname);
X		lp = lforw(lp);
X		}
X	(void) fclose(fp);
X	infof("Write successful.");
X	if (undo_term) {
X		renumber_lines(bp);
X		u_terminate();
X		}
X	(void) chmod(fn, bp->b_mode);
X	curbp = saved_bp;
X	return TRUE;
X}
X
X/*
X * Select a file for editing.
X * Look around to see if you can find the
X * fine in another buffer; if you can find it
X * just switch to the buffer. If you cannot find
X * the file, create a new buffer, read in the
X * text, and switch to the new buffer.
X */
Xfileedit()
X{	int	i;
X	char	*fname;
X	char	*cp;
X	char	buf[128];
X	char	buf1[128];
X	extern char *strtok();
X	int acnt = argc;
X	char	*cp1;
X
X	accumulator = 1;
X	if (argv[1].l_flags == F_NULL) {
X		if ((fname = get_arg1("Edit file: ", buf1, sizeof buf1)) == NULL) {
X			struct stat sbuf;
X			if (stat(curbp->b_fname, &sbuf) >= 0 && 
X				(sbuf.st_mode & S_IWRITE) == 0)
X				curbp->b_flag |= BFRO;
X			else
X				curbp->b_flag &= ~BFRO;
X			accumulator = 0;
X			return -1;
X			}
X		argv[1].l_str = fname;
X		argv[1].l_flags = F_LIT;
X		acnt = 2;
X		}
X	for (i = 1; i < acnt; i++) {
X		char	*file_name = get_str(i);
X		strcpy(buf, file_name);
X		cp1 = buf;
X		while (cp1) {
X			char fbuf[128];
X			int j;
X			extern char **shell_expand();
X			char	**files;
X
X			cp = strtok(cp1, " \t");
X			cp1 = strtok((char *) NULL, "\n");
X			if (cp == NULL || (files = shell_expand(cp)) == NULL) {
X				accumulator = 0;
X				errorf("Name expansion error.");
X				cp = cp1;
X				continue;
X				}
X			for (j = 0; files[j]; j++) {
X				if (files[j][0]) {
X					strcpy(fbuf, filename(files[j]));
X					if (atomic_fileedit(fbuf))
X						accumulator = 0;
X					}
X				chk_free(files[j]);
X				}
X			chk_free(files);
X			cp = cp1;
X			}
X		}
X	return 0;
X}
Xatomic_fileedit(fbuf)
Xchar	*fbuf;
X{
X	register BUFFER *bp;
X	int             s;
X	extern	char	*get_arg1();
X	extern MACRO *lookup_macro();
X	extern char *filename();
X	char	*cp;
X
X	if ((bp = findbuffer(fbuf, &s)) == NULL) return s;
X	showbuffer(bp, curwp);
X	curbp = bp;
X	if ((bp->b_flag & BFREAD) == 0) {
X		int	saved_system = bp->b_system;
X		bp->b_system = 2; /* Stops us saving undo info */
X		bp->b_flag |= BFREAD;
X		readin(bp, fbuf);         /* Read it in.          */
X		renumber_lines(bp);
X		bp->b_system = saved_system;
X		for (cp = fbuf+strlen(fbuf)-1; cp > fbuf; cp--)
X			if (*cp == '.' || *cp == '/')
X				break;
X		if (cp <= fbuf || *cp != '.')
X			cp = "default";
X		if (lookup_macro(cp))
X			str_exec(cp);
X		trigger(REG_NEW);
X		}
X	trigger(REG_EDIT);
X	accumulator = 1;
X	return 0;
X}
Xrdonly()
X{
X	if (curbp->b_flag & BFRO) {
X		errorf("File is read only");
X		return -1;
X		}
X	return 0;
X}
Xsecond_passed()
X{
X	static long last_time = 0;
X	extern long time();
X	long tnow = time((long *) 0);
X
X	if (tnow == last_time)
X		return FALSE;
X	last_time = tnow;
X	return TRUE;
X}
Xvoid
Xpercentage(a, b, str, str1)
Xlong	a, b;
Xchar	*str, *str1;
X{	static	long	pc = 0;
X	long	l = (a * 100) / b;
X
X	if (second_passed() == FALSE)
X		return;
X
X	if (pc != l && l) {
X		pc = l;
X		infof("[%s %s: %ld%% done]", str, str1, pc);
X		}
X}
X
X/*
X * Rename the file "fname" into a backup
X * copy. 
X */
Xfbackupfile(fname, perms)
Xchar    *fname;
X{
X	char	nname[NFILEN];
X	extern	char	*strrchr(), *ggetenv();
X	char	*cp;
X	char	*np;
X	char	*cp1 = strrchr(fname, '/');
X	struct stat stat_buf;
X
X	if (cp1)
X		cp1++;
X	else
X		cp1 = fname;
X
X	/*-----------------------------------------
X	 *   If file has more than one link to it,
X	 *   dont try and link the file to the backup
X	 *   directory otherwise we lose the link information
X	 *   and confuse the user.
X	 *-----------------------------------------*/
X	if (stat(fname, &stat_buf) < 0)
X		stat_buf.st_nlink = 1+1;
X	if (stat_buf.st_nlink == 1) {
X		/*-----------------------------------------
X	 	*   See if we can link file to backup
X	 	*   directory.
X	 	*-----------------------------------------*/
X		for (cp = ggetenv("BBACKUP"); cp && *cp; ) {
X			for (np = nname; *cp && *cp != ';'; )
X				*np++ = *cp++;
X			*np++ = '/';
X			if (*cp)
X				cp++;
X			strcpy(np, cp1);
X			(void) unlink(nname);
X			if ( link(fname, nname) >= 0 && unlink(fname) >= 0 )
X				return TRUE;
X			}
X		}
X	/*-----------------------------------------
X	 *   See if we can copy file to backup
X	 *   directory.
X	 *-----------------------------------------*/
X	for (cp = ggetenv("BBACKUP"); cp && *cp; ) {
X		for (np = nname; *cp && *cp != ';'; )
X			*np++ = *cp++;
X		*np++ = '/';
X		if (*cp)
X			cp++;
X		strcpy(np, cp1);
X		if (copy_file(fname, nname, perms) == FALSE)
X			continue;
X		return TRUE;
X		}
X	sprintf(nname, "%s.bak", fname);
X	if (stat_buf.st_nlink != 1)
X		return copy_file(fname, nname, perms);
X	(void) unlink(nname);                   /* Ignore errors.       */
X
X	/* no rename on System V, so do it dangerous way. */
X	if ( link(fname, nname) < 0 || unlink(fname) < 0 )
X		return (FALSE);
X	return (TRUE);
X}
Xcopy_file(fname, nname, perms)
Xchar	*fname;
Xchar	*nname;
X{	int	fd1, fd2;
X	char	buf[BUFSIZ];
X	int	n;
X
X	if ((fd1 = open(nname, O_WRONLY | O_CREAT | O_TRUNC)) < 0)
X		return FALSE;
X	if ((fd2 = open(fname, O_RDONLY)) < 0) {
X		close(fd1);
X		unlink(nname);
X		return TRUE;
X		}
X	chmod(nname, perms);
X	while ((n = read(fd2, buf, sizeof buf)) > 0)
X		write(fd1, buf, n);
X	close(fd1);
X	close(fd2);
X	return TRUE;
X}
Xset_backup()
X{
X	accumulator = do_backups;
X	if (argv[1].l_flags == F_NULL)
X		do_backups = !do_backups;
X	else
X		do_backups = argv[1].l_int;
X	infof("Backups will %sbe created.", do_backups ? "" : "not ");
X	return 0;
X}
Xfind_file()
X{
X	struct dirent	*de;
X	struct stat stat_buf;
X	char	buf[256];
X	
X	accumulator = 0;
X	if (dirp == NULL)
X		return;
X
X	while ((de = readdir(dirp)) != (struct dirent *) NULL) {
X		if (!wild_match(de->d_name, file_buf))
X			continue;
X		strcpy(buf, dir_buf);
X		strcat(buf, de->d_name);
X		stat(buf, &stat_buf);
X		if (argv[1].l_flags != F_NULL)
X			str_assign(argv[1].l_sym, de->d_name);
X		if (argv[2].l_flags != F_NULL)
X			argv[2].l_sym->s_int = stat_buf.st_size;
X		if (argv[3].l_flags != F_NULL)
X			argv[3].l_sym->s_int = stat_buf.st_mtime;
X		if (argv[4].l_flags != F_NULL)
X			argv[4].l_sym->s_int = stat_buf.st_ctime;
X		if (argv[5].l_flags != F_NULL)
X			argv[5].l_sym->s_int = stat_buf.st_mode;
X		accumulator = 1;
X		return;
X		}
X}
Xfile_pattern()
X{	char	*cp = get_str(1);
X	char	*filename;
X	char	*strrchr();
X	char	buf[BUFSIZ];
X	
X	strcpy(buf, cp);
X	cp = buf;
X	if (dirp)
X		closedir(dirp);
X	/*-------------------------------------
X	/*   Isolate directory name.
X	/*-------------------------------------*/
X	strncpy(file_buf, cp, sizeof file_buf - 1);
X	filename = strrchr(cp, '/');
X	if (filename == NULL) {
X		dirp = opendir(".");
X		filename = cp;
X		strcpy(dir_buf, "./");
X		}
X	else {
X		*filename++ = NULL;
X		dirp = opendir(cp);
X		strcpy(dir_buf, cp);
X		strcat(dir_buf, "/");
X		}
X	strncpy(file_buf, filename, sizeof file_buf - 1);
X}
SHAR_EOF
chmod 0444 ./file.c || echo "restore of ./file.c fails"
mkdir . >/dev/null 2>&1
echo "x - extracting ./keywd.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ./keywd.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
XSCCSID("@(#) keywd.c 1.35, (C) P. Fox");
X
Xint	cm_version = 8;
X
X# ifdef	NOFUNCTIONS
X# define	MACRO3(a,b,c)		{a, 0, c}
X# define	MACRO4(a,b,c,d)		{a, 0, c, d}
X# define	MACRO5(a,b,c,d,e)	{a, 0, c, d, e}
X# else
X# define	MACRO3(a,b,c)		{a, b, c}
X# define	MACRO4(a,b,c,d)		{a, b, c, d}
X# define	MACRO5(a,b,c,d,e)	{a, b, c, d, e}
Xint	andand(), append(), assign_to_key(), attach_buffer(), autoload(),
X	backspace(), beep(), beginning_of_line(), borders(),
X	call_registered_macro(), car(), color(), command_list(),
X	compress(), copy(), inq_file_buffer(),
X	com_equ(), com_op(), create_buffer(), cre_edge(), create_window(),
X	del_char(), inq_buffer_flags(),
X	do_abort(), do_atoi(), do_break(), do_cd(), do_connect(),
X	inq_kbd_char(), inq_lines(), lnot(), minusminus(), next_char(), nothing(), 
X	plusplus(), read_char(), use_tab_char(),
X	cdr(), change_window(), do_continue(), cut(), do_date(), 
X	do_debug(), declare(), del(), del_block(), del_buffer(), 
X	del_edge(), del_line(), del_to_eol(), del_window(), 
X	do_disconnect(), dist_to_tab(), do_shell(), key_down(), 
X	drop_anchor(), drop_bookmark(), set_echo_line(), fileedit(), 
X	enable_display(), gotoeob(), end_of_line(), end_of_window(), 
X	do_error(), exec_cmd(), exist(), do_exit(), do_extern(),
X	file_pattern(), find_file(), first_time(), get_parm(), 
X	gt_characters(), gt_features(), gt_keyboard(), do_getpid(),
X	do_getwd(), do_global(), goto_bookmark(), goto_line(), goto_old_line(),
X	do_ega(),
X	do_if(), do_index(), inq_assignment(), inq_buffer(), inq_called(), inq_cmd_line(),
X	inq_command(), inq_environment(), inq_idefault(), inq_itime(), inq_keyboard(), inq_line_length(),
X	inq_local_keyboard(), inq_macro(), inq_mksize(), inq_marked(), inq_message(), inq_mode(),
X	inq_modified(), inq_msg_level(), inq_names(), inq_position(), inq_scrap(), inq_screen_size(),
X	inq_system(), inq_views(), inq_w(), inq_window_size(), 
X	insert(), ins_mode(), int_to_key(), is_type(),
X	key_to_int(), kbd_pop(), kbd_push(), kbd_type(), key_left(), list_length(), load_macro(), do_lower(),
X	ltrim(), enter_macro(), mark(), message(), move_abs(), move_edge(),
X	make_local_variable(), display_mode(),
X	move_rel(), next_buffer(), nth(), output_file(), page_down(), page_up(),
X	paste(), do_pause(), pause_on_error(), playback(), prev_char(), do_printf(),
X	process(), do_profile(), push_back(), put_nth(), put_parm(), 
X	quote(), quote_regexp(), raise_anchor(),
X	do_read(), read_file(), redraw(), update(), register_macro(), remember(), 
X	restore_position(), returns(), re_syntax_fn(),
X	key_right(), do_rindex(), save_position(),
X	set_process_position(), inq_process_position(), screen_dump(),
X	search_list(), macro_list(), sort_buffer(),
X	search(), srch_case(), srch_string(), string_count(),
X	selfinsert(), set_backup(), set_buffer(), set_buffer_flags(),
X	set_msg_level(),
X	st_characters(), st_features(), st_keyboard(), set_top_left(),
X	set_display_chars(),
X	set_window(), do_sleep(), do_sprintf(), strip_cr(), do_strlen(),
X	substr(), swap_anchor(), do_switch(), do_tabs(), do_time(), gotobob(),
X	top_of_window(), transfer(), translate(), trim(), typeof(), undo(), 
X	unregister_macro(), key_up(), do_upper(), use_local_keyboard(), 
X	do_version(), p_wait(), p_wait_for(), do_while(), 
X	write_block(), filesave(), oror() 
X	;
X# endif
X/*--------------------------------------------------*/
X/*   Keyword table. Must be in alphabetic order.    */
X/*   *     following argument is optional.          */
X/*   a     must evaluate to string or list.         */
X/*   b     must evaluate to string or integer.      */
X/*   i     must evaluate to integer.                */
X/*   l     must evaluate to a list.                 */
X/*   m     macro name - symbol which isn't evaluated.*/
X/*   s     must evaluate to string.                 */
X/*   t     must evaluate to string, integer or list.*/
X/*         (Triple type).                           */
X/*   B     must be a symbol of type string or integer.*/
X/*   C     list to be conditionally evaluated.      */
X/*   I     must be a symbol of type integer.        */
X/*   L     must be a symbol of type list.           */
X/*   R     rest of argument list treated as a list. */
X/*   S     must be a symbol of type string.         */
X/*   T     must be a symbol of type string, integer */
X/*         or list. (Triple type).                  */
X/*--------------------------------------------------*/
XBUILTIN builtin[] = {
XMACRO3("!",			lnot,		"i"),		/* Arith */
XMACRO5("!=",			com_op,		"bb", 0, NE),	/* Arith, */
XMACRO5("%",			com_op,		"ii", 0, MODULO),/* Arith */
XMACRO5("%=",			com_equ,	"Ii", 0, MODULO),/* Arith */
XMACRO5("&",			com_op,		"ii", 0, BAND),/* Arith */
XMACRO3("&&",			andand,		"iC"),	/* Arith */
XMACRO5("&=",			com_equ,	"Ii", 0, BAND), /* Arith */
XMACRO5("*",			com_op,		"ii", 0, MULTIPLY), /* Arith */
XMACRO5("*=",			com_equ,	"Ii", 0, MULTIPLY), /* Arith */
XMACRO5("+",			com_op,		"bb", 0, PLUS),/* Arith */
XMACRO3("++",			plusplus,	"I"),/* Arith */
XMACRO5("+=",			com_equ,	"Bb", 0, PLUS),/* Arith */
XMACRO5("-",			com_op,		"ii", 0, MINUS),/* Arith */
XMACRO3("--",			minusminus,	"I"),/* Arith */
XMACRO5("-=",			com_equ,	"Ii", 0, MINUS),/* Arith */
XMACRO5("/",			com_op,		"ii", 0, DIVIDE),/* Arith */
XMACRO5("/=",			com_equ,	"Ii", 0, DIVIDE),/* Arith */
XMACRO5("<",			com_op,		"bb", 0, LT),/* Arith, */
XMACRO5("<=",			com_op,		"bb", 0, LE),/* Arith, */
XMACRO5("=",			com_equ,	"T*t", 0, NOOP),/* Arith */
XMACRO5("==",			com_op,		"bb", 0, EQ),/* Arith */
XMACRO5(">",			com_op,		"bb", 0, GT),/* Arith */
XMACRO5(">=",			com_op,		"bb", 0, GE),/* Arith */
XMACRO5("^",			com_op,		"ii", 0, BXOR),/* Arith */
XMACRO5("^=",			com_equ,	"Ii", 0, BXOR), /* Arith */
XMACRO3("_bad_key",		nothing,	""),/* Misc */
XMACRO3("abort",			do_abort,	""),/* Debug */
XMACRO5("above",			com_op,		"ii", 0, ABOVE),/* Arith */
XMACRO5("above_eq",		com_op,		"ii", 0, ABOVE_EQ),/* Arith */
XMACRO3("append_list",		append,		"Ll"),/* List */
XMACRO4("assign_to_key",		assign_to_key,	"*s*a",	B_NOVALUE),/* Kbd */
XMACRO3("atoi",			do_atoi,	"s*i"),/* String */
XMACRO3("attach_buffer",		attach_buffer,	"i"),/* Buffer */
XMACRO4("autoload",		autoload,	"sR",	B_NOVALUE),/* Macro */
XMACRO3("backspace",		backspace,	""),/* Movement, */
XMACRO3("beep",			beep,		""),/* Misc */
XMACRO3("beginning_of_line",	beginning_of_line, ""),/* Movement, */
XMACRO5("below",			com_op,		"ii", 0, BELOW),/* Arith */
XMACRO5("below_eq",		com_op,		"ii", 0, BELOW_EQ),/* Arith */
XMACRO3("borders",		borders,	"*i"),/* Screen */
XMACRO3("break",			do_break,	""),/* Macro */
XMACRO3("call_registered_macro",	call_registered_macro, "i"),/* Macro */
XMACRO3("car",			car,		"l"),/* List */
XMACRO3("cd",			do_cd,		"*s"),/* Env */
XMACRO3("cdr",			cdr,		"l"),/* List */
XMACRO3("change_window",		change_window,	"*i"),/* Window */
XMACRO3("color",			color,		"*i*i*i*i*i*i"),/* Screen */
XMACRO3("command_list",		command_list,	""),/* List */
XMACRO3("compress",		compress,	"s"),/* String */
XMACRO3("connect",		do_connect,	"*i*s"),/* Proc */
XMACRO3("continue",		do_continue,	""),/* Macro */
XMACRO3("copy",			copy,		"*i"),/* Scrap */
XMACRO3("create_buffer",		create_buffer,	"s*s*i"),/* Buffer */
XMACRO3("create_edge",		cre_edge,	"*i"),/* Window */
XMACRO3("create_window",		create_window,	"iiii*s"),/* Window */
XMACRO3("cut",			cut,		""),/* Scrap */
XMACRO3("date",			do_date,	"*I*I*I*S*S"),/* Misc */
XMACRO3("debug",			do_debug,	"*i"),/* Debug */
XMACRO5("declare",		declare,	"R", B_NOVALUE, F_POLY),/* Var */
XMACRO3("del",			del,		"s"),/* File */
XMACRO3("delete_block",		del_block,	""),/* Scrap */
XMACRO3("delete_buffer",		del_buffer,	"i"),/* Buffer */
XMACRO3("delete_char",		del_char,	"*i"),/* Buffer */
XMACRO3("delete_edge",		del_edge,	"*i"),/* Window */
XMACRO3("delete_line",		del_line,	""),/* Buffer */
XMACRO3("delete_macro",		0,		"*s"),/* Macro */
XMACRO3("delete_to_eol",		del_to_eol,	""),/* Buffer */
XMACRO3("delete_window",		del_window,	""),/* Window */
XMACRO3("disconnect",		do_disconnect,	""),/* Proc */
XMACRO3("display_mode",  	display_mode,	"*i"),/* Screen */
XMACRO3("distance_to_tab",	dist_to_tab,	""),/* Buffer, Window */
XMACRO3("dos",			do_shell,	"*s*i*s"),/* Env, Proc */
XMACRO3("down",			key_down,	"*i"),/* Movement */
XMACRO3("drop_anchor",		drop_anchor,	"*i"),/* Scrap */
XMACRO3("drop_bookmark",		drop_bookmark,	"*i*s*i*i*i"),/* Movement */
XMACRO3("echo_line",		set_echo_line,	"*i"),/* Screen */
XMACRO3("edit_file",		fileedit,	"*s*s*s*s*s*s*s*s*s*s*s"),/* File */
XMACRO3("ega",			do_ega,		"*i"),/* Screen */
XMACRO3("enable_display",	enable_display,	"*i"),/* Screen */
XMACRO3("end_of_buffer",		gotoeob,	""),/* Movement */
XMACRO3("end_of_line",		end_of_line,	""),/* Movement */
XMACRO3("end_of_window",		end_of_window,	""),/* Movement */
XMACRO3("error",			do_error,	"s*b*b*b*b"),/* Debug */
XMACRO3("execute_macro",		exec_cmd,	"*s*R"),/* Macro */
XMACRO3("exist",			exist,		"s"),/* File */
XMACRO3("exit",			do_exit,	"*s"),/* Macro */
XMACRO3("extern",		do_extern,	"R"),/* Var */
XMACRO3("file_pattern",		file_pattern,	"s"),/* File */
XMACRO3("find_file",		find_file,	"*S*I*I*I*I"),/* File */
XMACRO3("first_time",		first_time,	""),/* Macro */
XMACRO3("get_parm",		get_parm,	"*iT*s*i*b"),/* Macro, Var */
XMACRO4("get_term_characters",	gt_characters,	"*b*b*b*b*b*b*b*b*b*b*b", B_NOVALUE),/* Screen, Env */
XMACRO4("get_term_features",	gt_features,	"R", B_NOVALUE),/* Screen, Env */
XMACRO4("get_term_keyboard",	gt_keyboard,	"R", B_NOVALUE),/* Screen, Env */
XMACRO3("getpid",		do_getpid,	""),/* Env */
XMACRO3("getwd",			do_getwd,	"*sS"),/* Env */
XMACRO4("global",		do_global,	"R",	B_NOVALUE),/* Var */
XMACRO3("goto_bookmark",		goto_bookmark,	"*i*I*I*I"),/* Buffer, */
XMACRO3("goto_line",		goto_line,	"*i"),/* Movement */
XMACRO3("goto_old_line",		goto_old_line,	"i"),/* Movement */
XMACRO3("if",			do_if,		"iC*C"),/* Macro */
XMACRO3("index",			do_index,	"ss"),/* String */
XMACRO3("inq_assignment",	inq_assignment,	"b*i"),/* Kbd */
XMACRO3("inq_borders",		0,		""),/* Screen */
XMACRO3("inq_brief_level",	0,		""),/* Env */
XMACRO3("inq_buffer",		inq_buffer,	""),/* Buffer */
XMACRO3("inq_buffer_flags",	inq_buffer_flags,"*i"),/* Buffer */
XMACRO3("inq_called",		inq_called,	""),/* Macro */
XMACRO3("inq_cmd_line",		inq_cmd_line,	""),/* Screen */
XMACRO3("inq_command",		inq_command,	""),/* Screen */
XMACRO3("inq_environment",	inq_environment, "s"),/* Env */
XMACRO3("inq_file_buffer",	inq_file_buffer, "s"),/* Buffer, File */
XMACRO3("inq_idle_default",	inq_idefault,	""),/* Env */
XMACRO3("inq_idle_time",		inq_itime,	""),/* Env */
XMACRO3("inq_kbd_char",		inq_kbd_char,	""),/* Kbd */
XMACRO3("inq_keyboard",		inq_keyboard,	""),/* Kbd */
XMACRO3("inq_line_length",	inq_line_length, "*i"),/* Buffer */
XMACRO3("inq_lines",		inq_lines, 	""),/* Buffer */
XMACRO3("inq_local_keyboard",	inq_local_keyboard, ""),/* Kbd */
XMACRO3("inq_macro",		inq_macro,	"s"),/* Macro */
XMACRO3("inq_mark_size",		inq_mksize,	""),/* Scrap */
XMACRO3("inq_marked",		inq_marked,	"*I*I*I*I"),/* Scrap */
XMACRO3("inq_message",		inq_message,	""),/* Screen */
XMACRO3("inq_mode",		inq_mode,	""),/* Buffer, Window */
XMACRO3("inq_modified",		inq_modified,	"*i"),/* Buffer */
XMACRO3("inq_msg_level",		inq_msg_level,	""),/* Macro */
XMACRO3("inq_names",		inq_names,	"*S*S*S"),/* Buffer */
XMACRO3("inq_position",		inq_position,	"*I*I"),/* Window, Buffer */
XMACRO3("inq_process_position",	inq_process_position,	"*I*I"),/* Proc, Buffer */
XMACRO3("inq_scrap",		inq_scrap,	"*I*I"),/* Scrap */
XMACRO3("inq_screen_size",	inq_screen_size, "*I*I"),/* Screen */
XMACRO3("inq_system",		inq_system,	""),/* Buffer */
XMACRO3("inq_views",		inq_views,	"*i"),/* Buffer, Window */
XMACRO3("inq_window",		inq_w,		""),/* Window */
XMACRO3("inq_window_color",	0,		""),/* Window, Screen */
XMACRO3("inq_window_size",	inq_window_size, "*I*I*I"),/* Window, Screen */
XMACRO5("insert",		insert,		"s*i", 0, FALSE),/* Buffer, Window */
XMACRO3("insert_mode",		ins_mode,	"*i"),/* Buffer, Window */
XMACRO5("insert_process",	insert,		"s*i", 0, TRUE),/* Buffer, Window, Proc */
XMACRO5("int",			declare,	"R",	B_NOVALUE, F_INT),/* Var */
XMACRO3("int_to_key",		int_to_key,	"i"),/* Kbd */
XMACRO5("is_integer",		is_type,   	"T", 0, F_INT),/* Var */
XMACRO5("is_list",		is_type,   	"T", 0, F_LIST),/* Var */
XMACRO5("is_null",		is_type,   	"T", 0, F_NULL),/* Var */
XMACRO5("is_string",		is_type,   	"T", 0, F_STR),/* Var */
XMACRO3("key_to_int",		key_to_int,	"s"),/* Kbd */
XMACRO3("keyboard_flush",	nothing,	""),/* Kbd */
XMACRO3("keyboard_pop",		kbd_pop,	"*i"),/* Kbd */
XMACRO3("keyboard_push",		kbd_push,	"*i"),/* Kbd */
XMACRO3("keyboard_typeables",	kbd_type,	""),/* Kbd */
XMACRO3("left",			key_left,	"*i"),/* Movement */
XMACRO3("length_of_list",	list_length,	"l"),/* List */
XMACRO5("list",			declare,	"R",	B_NOVALUE, F_LIST),/* Var, List */
XMACRO3("load_macro",		load_macro,	"*s"),/* Macro */
XMACRO3("lower",			do_lower,	"s"),/* String */
XMACRO3("ltrim",			ltrim,		"s"),/* String */
XMACRO4("macro",			enter_macro,	"mR",	B_NOVALUE),/* Macro, */
XMACRO3("macro_list",		macro_list,	""),/* String, List */
XMACRO4("make_local_variable",	make_local_variable, "R", B_NOVALUE),/* Var */
XMACRO3("mark",			mark,		"*i"),/* Scrap */
XMACRO3("message",		message,	"s*b*b*b*b*b*b"),/* Debug */
XMACRO3("move_abs",		move_abs,	"*i*i"),/* Movement */
XMACRO3("move_edge",		move_edge,	"*i*i"),/* Window */
XMACRO3("move_rel",		move_rel,	"*i*i"),/* Movement */
XMACRO3("next_buffer",		next_buffer,	"*i"),/* Buffer */
XMACRO3("next_char",		next_char,	"*i"),/* Movement */
XMACRO3("nothing",		nothing,	""),/* Macro */
XMACRO3("nth",			nth,		"il"),/* List */
XMACRO3("output_file",		output_file,	"*s"),/* File */
XMACRO3("page_down",		page_down,	""),/* Movement */
XMACRO3("page_up",		page_up,	""),/* Movement */
XMACRO3("paste",			paste,		""),/* Scrap */
XMACRO3("pause",			do_pause,	""),/* Kbd */
XMACRO3("pause_on_error",	pause_on_error,	"*i"),/* Debug */
XMACRO3("playback",		playback,	"*i"),/* Kbd */
XMACRO3("prev_char",		prev_char,	"*i"),/* Movement */
XMACRO3("print",			0,		""),/* Debug */
XMACRO3("printf",		do_printf,	"s*b*b*b*b*b*b*b*b"),/* Debug */
XMACRO3("process",		process,	""),/* Kbd */
XMACRO3("profile",		do_profile,	"*i"),/* Debug */
XMACRO3("push_back",		push_back,	"i"),/* Kbd */
XMACRO3("put_nth",		put_nth,	"iLt"),/* List */
XMACRO3("put_parm",		put_parm,	"ib"),/* Macro, Var */
XMACRO3("quote_list",		quote,		"R"),/* List */
XMACRO3("quote_regexp",		quote_regexp,	"s"),/* String, Search */
XMACRO3("raise_anchor",		raise_anchor,	""),/* Scrap */
XMACRO3("re_syntax",		re_syntax_fn,	"*i"),/* Search */
XMACRO3("read",			do_read,	"*i"),/* String */
XMACRO3("read_char",		read_char,	""),/* Kbd */
XMACRO3("read_file",		read_file,	"*s"),/* File */
XMACRO3("redraw",		redraw,		""),/* Screen */
XMACRO3("refresh",		update,		""),/* Screen */
XMACRO3("register_macro",	register_macro,	"is*i"),/* Macro */
XMACRO3("remember",		remember,	"*s*i"),/* Kbd */
XMACRO4("replacement",		enter_macro,	"mR",	B_NOVALUE),/* */
XMACRO3("restore_position",	restore_position, "*i"),/* Movement, Macro */
XMACRO5("return",		returns,	"*t", 0, FALSE),/* Macro */
XMACRO5("returns",		returns,	"t", 0, TRUE),/* Macro */
XMACRO3("right",			key_right,	"*i"),/* Buffer, Window */
XMACRO3("rindex",		do_rindex,	"ss"),/* String */
XMACRO3("save_position",		save_position,	""),/* Movement, Macro */
XMACRO3("screen_dump",		screen_dump,	"*s"),/* Screen */
XMACRO5("search_back",		search,		"*s*i*i*i*i", 0, FALSE),/* Movement, Search */
XMACRO3("search_case",		srch_case,	"*i"),/* Search */
XMACRO5("search_fwd",		search,		"*s*i*i*i*i", 0, TRUE),/* Movement, Search */
XMACRO3("search_list",		search_list,	"*isl*i*i"),/* Search, List */
XMACRO3("search_string",		srch_string,	"ss*I*i*i"),/* Search, String */
XMACRO3("self_insert",		selfinsert,	"*i"),/* Kbd, Buffer, Window */
XMACRO3("set_backup",		set_backup,	"*i"),/* Env */
XMACRO3("set_buffer",		set_buffer,	"i"),/* Buffer */
XMACRO3("set_buffer_flags",	set_buffer_flags,	"*i*i"),/* Buffer */
XMACRO3("set_calling_name",	0,		""),/* Macro */
XMACRO4("set_display_chars",	set_display_chars,"R", B_NOVALUE),/* Screen, Env */
XMACRO3("set_msg_level",		set_msg_level,	"i"),/* Misc */
XMACRO3("set_process_position",	set_process_position,	"*i*i"),/* Proc, Buffer */
XMACRO3("set_scrap_info",	0,		"i"),/* Scrap */
XMACRO4("set_term_characters",	st_characters,	"R", B_NOVALUE),/* Screen, Env */
XMACRO4("set_term_features",	st_features,	"R", B_NOVALUE),/* Screen, Env */
XMACRO4("set_term_keyboard",	st_keyboard,	"R", B_NOVALUE),/* Screen, Env */
XMACRO3("set_top_left",		set_top_left,	"*i*i"),/* Movement, Buffer, Window */
XMACRO3("set_window",		set_window,	"i"),/* Window */
XMACRO3("shell",			do_shell,	"*s*i*s"),/* Env, Proc */
XMACRO3("sleep",			do_sleep,	"*i"),/* Proc */
XMACRO3("sort_buffer",		sort_buffer,	"*i"),/* Buffer */
XMACRO4("sprintf",		do_sprintf,	"Ss*b*b*b*b*b*b*b*b*b", B_NOVALUE),/* String */
XMACRO5("string",		declare,	"R",	B_NOVALUE, F_STR),/* Var */
XMACRO3("string_count",		string_count,	"ss"),/* String */
XMACRO3("strip_cr",		strip_cr,	"*i"),/* File, Env */
XMACRO3("strlen",		do_strlen,	"s"),/* String */
XMACRO3("substr",		substr,		"si*i"),/* String */
XMACRO3("swap_anchor",		swap_anchor,	""),/* Scrap, Movement */
XMACRO3("switch",		do_switch,	"bR"),/* Macro */
XMACRO3("tabs",			do_tabs,	"*i*i*i*i*i*i"),/* Buffer */
XMACRO3("time",			do_time,	"*I*I*I"),/* Misc */
XMACRO3("top_of_buffer",		gotobob,	""),/* Movement */
XMACRO3("top_of_window",		top_of_window,	""),/* Movement */
XMACRO3("transfer",		transfer, 	"iiiii"),/* Scrap */
XMACRO3("translate",		translate,	"*s*s*i*i*i*i*i"),/* Search */
XMACRO3("trim",			trim,		"s"),/* String*/
XMACRO3("typeof",		typeof,		"*t"),/* Var */
XMACRO3("undo",			undo,		"*i*i*i"),/* Kbd, Misc */
XMACRO3("unregister_macro",	unregister_macro, "is*i"),/* Macro */
XMACRO3("up",			key_up,		"*i"),/* Buffer, Window */
XMACRO3("upper",			do_upper,	"s"),/* String */
XMACRO3("use_local_keyboard",	use_local_keyboard, "i"),/* Kbd */
XMACRO3("use_tab_char",		use_tab_char,	"*s"),/* Env, Screen */
XMACRO3("version",		do_version,	""),/* Misc */
XMACRO3("wait",			p_wait,		"*I"),/* Proc */
XMACRO3("wait_for",		p_wait_for,	"*i*a"),/* Proc */
XMACRO3("watch",			0,		""),/* Debug */
XMACRO3("while",			do_while,	"C*R"),/* Macro */
XMACRO3("window_color",		window_color,	"*i"),/* Window, Screen */
XMACRO3("write_block",		write_block,	"*s*i"),/* Scrap */
XMACRO3("write_buffer",		filesave,	"*s*i"),/* File, Buffer */
XMACRO5("|",			com_op,		"ii", 0, BOR),/* Arith */
XMACRO5("|=",			com_equ,	"Ii", 0, BOR), /* Arith */
XMACRO3("||",			oror,		"iC"),/* Arith */
XMACRO5("~",			com_op,		"i", 0, BNOT),/* Arith */
X	};
X
Xint	sizeof_builtin = sizeof builtin / sizeof (BUILTIN);
X
Xvoid
Xinit_builtin()
X{	register int	i;
X	register BUILTIN *bp = builtin;
X	static LIST f_halt = F_HALT;
X
X	for (i = 0; i < sizeof_builtin; i++, bp++)
X		bp->argv = &f_halt;
X}
Xb_compare(b1, b2)
Xregister char	*b1;
XBUILTIN	*b2;
X{	register char	*t = b2->name;
X	for ( ; *b1 == *t; b1++, t++)
X		if (*b1 == 0)
X			return 0;
X	return *b1 - *t;
X}
XBUILTIN *
Xlookup_builtin(str)
Xchar	*str;
X{	extern char	*bsearch();
X
X	return (BUILTIN *) bsearch(str, (char *) builtin, 
X			sizeof_builtin,	sizeof (BUILTIN), b_compare);
X}
SHAR_EOF
chmod 0444 ./keywd.c || echo "restore of ./keywd.c fails"
mkdir . >/dev/null 2>&1
echo "x - extracting ./kill.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ./kill.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
XSCCSID("@(#) kill.c 1.7, (C) 1989, P. Fox");
X
X# define	K_START BUFFER *saved_bp = curbp; \
X				curbp = scrbp; \
X				set_hooked()
X# define	K_END	curbp = saved_bp; \
X			set_hooked()
X
Xint	scrap_type;
Xextern	BUFFER	*scrap_bp;
XBUFFER	*scrbp;
Xstatic	LINE	*klp;
Xstatic	int	kline;
Xinq_scrap()
X{
X	if (argv[2].l_flags == F_INT)
X		argv[2].l_sym->s_int = scrap_type;
X	accumulator = scrap_bp->b_bufnum;
X	return 0;
X}
Xvoid
Xk_init()
X{
X	scrbp = scrap_bp;
X}
Xvoid	
Xk_delete(n) 
X{	
X	register LINE *lp;
X	int	line = 1;
X	RSIZE	nbytes = 0;
X	K_START;
X	
X	scrap_type = n;
X	for (lp = linep(1); line < scrbp->b_numlines; line++) {
X		nbytes += llength(lp) + 1;
X		lp = lforw(lp);
X		}
X	*cur_line = 1;
X	*cur_col = 1;
X	if (nbytes > 0)
X		nbytes--;
X	if (nbytes)
X		u_insert(nbytes);
X	bclear(scrbp);
X	K_END;
X}
Xvoid
Xk_write(buf, cnt)
Xu_char	*buf;
Xint	cnt;
X{	K_START;
X
X	llinsert(buf, cnt, FALSE);
X	K_END;
X}
Xk_type()
X{
X	return scrap_type;
X}
Xvoid
Xk_newline() 
X{	K_START;
X	lnewline('\n');
X	K_END;
X}
Xk_seek()
X{
X	klp = lforw(scrbp->b_linep);
X	kline = 1;
X}
Xk_read(cpp)
Xchar	**cpp;
X{	int	used = klp->l_used;
X	if (klp == scrbp->b_linep)
X		return -1;
X	*cpp = (char *) klp->l_text;
X	klp = lforw(klp);
X	return used;
X}
Xk_undo()
X{
X	K_START;
X	undo();
X	K_END;
X}
Xk_end()
X{
X	K_START;
X	u_chain();
X	K_END;
X}
SHAR_EOF
chmod 0444 ./kill.c || echo "restore of ./kill.c fails"
mkdir . >/dev/null 2>&1
echo "x - extracting ./language.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ./language.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	"cm.h"
X
XSCCSID("@(#) language.c 1.17, (C) P. Fox");
Xint	 fstat();
X
X# define	FBUFSIZ		1024
X# define	MAX_CM_SIZE	65530
X# define	YYMAX	128
X
X# define	_XDIGIT		0x01
X# define	_XSYMBOL	0x02
X# define	_XWS		0x04
X# define	_XISPRINT	0x08	/* Used by printable_char() function */
X					/* in display.c			     */
X# define	_XTABESC	0x10 	/* Set for tabs and <Esc>. Used by   */
X					/* char_width() in map.c	     */
X# define	TOKEN_EOF	0
X# define	OPEN_PAREN	1
X# define	CLOSE_PAREN	2
X# define	ID		3
X# define	INT		4
X# define	STR		5
X# define	NATOMS	2048
X# define	NMACROS	256
XHead_p		hd_syms;
X
Xvoid	get_until();
Xvoid	yyerror();
Xvoid	cpp();
Xvoid	do_include();
Xvoid	do_define();
Xextern u_int16 WGET16();
Xextern u_int32 WGET32();
X
Xint	pending_macros[NMACROS];	/* List of macros to be inserted. */
Xint	npending;
XLIST	*first_atom;
Xint	sizeof_macro;			/* Size of macro in atoms.	  */
Xint	verbose_errors = TRUE;
X
Xint	sizeof_atoms[] = {
X		1,		/* F_HALT	*/
X		5,		/* F_INT	*/
X		5,		/* F_STR	*/
X		3,		/* F_LIST	*/
X		1,		/* F_NULL	*/
X		3,		/* F_ID		*/
X		1,		/* F_END	*/
X		1,		/* F_POLY	*/
X		5,		/* F_LIT	*/
X		5,		/* F_RSTR	*/
X		};
X
Xunsigned char _chars_[256] = {
X/* | nul| soh| stx| etx| eot| enq| ack| bel| */
X	0,  0,  0,  0,  0,  0,  0,  0,	/* 0x00 - 0x07 */
X/* | bs | ht | nl | vt | np | cr | so | si | */
X        0,0x14,  0,  0,  4,  0,  0,  0,	/* 0x08 - 0x0f */
X/* | dle| dc1| dc2| dc3| dc4| nak| syn| etb| */
X	0,  0,  0,  0,  0,  0,  0,  0,	/* 0x10 - 0x17 */
X/* | can| em | sub| esc| fs | gs | rs | us | */
X	0,  0,  0,0x10,  0,  0,  0,  0,	/* 0x18 - 0x0f */
X/* | sp |  ! |  " |  # |  $ |  % |  & |  ' | */
X    0x0c,0x0a,0x08,0x08,0x0a,0x0a,0x0a,0x08,
X/* |  ( |  ) |  * |  + |  , |  - |  . |  / | */
X    0x08,0x08,0x0a,0x0a,0x08,0x0a,0x0a,0x0a,
X/* |  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7 | */
X    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
SHAR_EOF
echo "End of part 5"
echo "File ./language.c is continued in part 6"
echo "6" > 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