v08i021: The JOVE text editor, Part02/13

sources-request at mirror.UUCP sources-request at mirror.UUCP
Wed Feb 4 14:56:47 AEST 1987


Submitted by: seismo!rochester!jpayne (Jonathan Payne)
Mod.sources: Volume 8, Issue 21
Archive-name: jove/Part02

#! /bin/sh
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# If all goes well, you will see the message "End of archive 2 (of 13)."
# Contents:  c.c ctype.c delete.c disp.c fmt.c re.h rec.h
#   doc/cmds.doc.nr
PATH=/bin:/usr/bin:/usr/ucb; export PATH
echo shar: extracting "'c.c'" '(13187 characters)'
if test -f 'c.c' ; then 
  echo shar: will not over-write existing file "'c.c'"
else
sed 's/^X//' >c.c <<'@//E*O*F c.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
X * provided to you without charge, and with no warranty.  You may give  *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files.                                           *
X ************************************************************************/
X
X/* Contains commands for C mode.  Paren matching routines are in here. */
X
X#include "jove.h"
X#include "re.h"
X#include "ctype.h"
X
Xprivate
Xbackslashed(lp, cpos)
Xregister char	*lp;
Xregister int	cpos;
X{
X	register int	cnt = 0;
X
X	while (cpos > 0 && lp[--cpos] == '\\')
X		cnt++;
X	return (cnt % 2);
X}
X
Xprivate char	*p_types = "(){}[]";
Xprivate int	mp_kind;
X#define MP_OKAY		0
X#define MP_MISMATCH	1
X#define MP_UNBALANCED	2
X
Xmp_error()
X{
X	switch (mp_kind) {
X	case MP_MISMATCH:
X		message("[Mismatched parentheses]");
X		break;
X
X	case MP_UNBALANCED:
X		message("[Unbalanced parenthesis]");
X		break;
X
X	case MP_OKAY:
X	default:
X		return;
X	}
X	rbell();
X}
X
X/* Search from the current position for the paren that matches p_type.
X   Search in the direction dir.  If can_mismatch is YES then it is okay
X   to have mismatched parens.  If stop_early is YES then when an open
X   paren is found at the beginning of a line, it is assumed that there
X   is no point in backing up further.  This is so when you hit tab or
X   LineFeed outside, in-between procedure/function definitions, it won't
X   sit there searching all the way to the beginning of the file for a
X   match that doesn't exist.  {forward,backward}-s-expression are the
X   only ones that insist on getting the "true" story. */
X
XBufpos *
Xm_paren(p_type, dir, can_mismatch, can_stop)
Xchar	p_type;
Xregister int	dir;
X{
X	static Bufpos	ret;
X	Bufpos	savedot,
X		*sp;
X	char	re_buf[100],
X		*re_alts[NALTS];
X	int	count = 0;
X	register char	*lp,
X			c;
X	char	p_match,
X		re_str[128],
X		*cp,
X		quote_c = 0;
X	register int	c_char;
X	int	in_comment = NO,
X		stopped = NO;
X
X	sprintf(re_str, "[(){}[\\]%s]", (MajorMode(CMODE)) ? "/\"'" : "\"");
X	REcompile(re_str, 1, re_buf, re_alts);
X	if (cp = index(p_types, p_type))
X		p_match = cp[dir];
X	else
X		complain("[Cannot match %c's]", p_type);
X	DOTsave(&savedot);
X
X	/* To make things a little faster I avoid copying lines into
X	   linebuf by setting curline and curchar by hand.  Warning:
X	   this is slightly to very risky.  When I did this there were
X	   lots of problems with procedures that expect the contents of
X	   curline to be in linebuf. */
X	while (count >= 0) {
X		sp = docompiled(dir, re_buf, re_alts);
X		if (sp == 0)
X			break;
X		lp = lbptr(sp->p_line);
X
X		curline = sp->p_line;
X		curchar = sp->p_char;	/* here's where I cheat */
X		c_char = curchar;
X		if (dir == FORWARD)
X			c_char--;
X
X		if (backslashed(lp, c_char))
X			continue;
X		c = lp[c_char];
X		/* check if this is a comment (if we're not inside quotes) */
X		if (quote_c == 0 && c == '/') {
X			if ((c_char != 0) && lp[c_char - 1] == '*')
X				in_comment = (dir == FORWARD) ? NO : YES;
X			else if (lp[c_char + 1] == '*')
X				in_comment = (dir == FORWARD) ? YES : NO;
X		}
X		if (in_comment)
X			continue;
X		if (c == '"' || c == '\'') {
X			if (quote_c == c)
X				quote_c = 0;
X			else if (quote_c == 0)
X				quote_c = c;
X		}
X		if (quote_c != 0)
X			continue;
X		if (isopenp(c)) {
X			count += dir;
X			if (c_char == 0 && can_stop == YES && count >= 0) {
X				stopped = YES;
X				break;
X			}
X		} else if (isclosep(c))
X			count -= dir;
X	}
X
X	ret.p_line = curline;
X	ret.p_char = curchar;
X
X	curline = savedot.p_line;
X	curchar = savedot.p_char;	/* here's where I undo it */
X
X	if (count >= 0)
X		mp_kind = MP_UNBALANCED;
X	else if (c != p_match)
X		mp_kind = MP_MISMATCH;
X	else
X		mp_kind = MP_OKAY;
X
X	/* If we stopped (which means we were allowed to stop) and there
X	   was an error, we clear the error so no error message is printed.
X	   An error should be printed ONLY when we are sure about the fact,
X	   namely we didn't stop prematurely HOPING that it was the right
X	   answer. */
X	if (stopped && mp_kind != MP_OKAY) {
X		mp_kind = MP_OKAY;
X		return 0;
X	}
X	if (mp_kind == MP_OKAY || (mp_kind == MP_MISMATCH && can_mismatch == YES))
X		return &ret;
X	return 0;
X}
X
Xprivate
Xdo_expr(dir, skip_words)
Xregister int	dir;
X{
X	register char	c,
X			syntax = (dir == FORWARD) ? _Op : _Cl;
X
X	exp = 1;
X	if (dir == BACKWARD)
X		BackChar();
X	c = linebuf[curchar];
X	for (;;) {
X		if (!skip_words && ismword(c)) {
X		    WITH_TABLE(curbuf->b_major)
X			(dir == FORWARD) ? ForWord() : BackWord();
X		    END_TABLE();
X		    break;
X		} else if (has_syntax(c, syntax)) {
X			FindMatch(dir);
X			break;
X		}
X		DoTimes(ForChar(), dir);
X		if (eobp() || bobp())
X			return;
X		c = linebuf[curchar];
X	}
X}
X
XFSexpr()
X{
X	register int	num = exp;
X
X	if (exp < 0) {
X		exp = -exp;
X		BSexpr();
X	}
X	while (--num >= 0)
X		do_expr(FORWARD, NO);
X}
X
XFList()
X{
X	register int	num = exp;
X
X	if (exp < 0) {
X		exp = -exp;
X		BList();
X	}
X	while (--num >= 0)
X		do_expr(FORWARD, YES);
X}
X
XBSexpr()
X{
X	register int	num = exp;
X
X	if (exp < 0) {
X		exp = -exp;
X		FSexpr();
X	}
X	while (--num >= 0)
X		do_expr(BACKWARD, NO);
X}
X
XBList()
X{
X	register int	num = exp;
X
X	if (exp < 0) {
X		exp = -exp;
X		FList();
X	}
X	while (--num >= 0)
X		do_expr(BACKWARD, YES);
X}
X
XBUpList()
X{
X	Bufpos	*mp;
X	char	c = (MajorMode(CMODE) ? '}' : ')');
X
X	mp = m_paren(c, BACKWARD, NO, YES);
X	if (mp == 0)
X		mp_error();
X	else
X		SetDot(mp);
X}
X
XFDownList()
X{
X	Bufpos	*sp;
X	char	*sstr = (MajorMode(CMODE) ? "[{([\\])}]" : "[()]"),
X		*lp;
X
X	sp = dosearch(sstr, FORWARD, YES);
X	if (sp != 0)
X		lp = lcontents(sp->p_line);
X	if (sp == 0 || has_syntax(lp[sp->p_char - 1], _Cl))
X		complain("[No contained expression]");
X	SetDot(sp);
X}
X
X/* Move to the matching brace or paren depending on the current position
X   in the buffer. */
X
Xprivate
XFindMatch(dir)
X{
X	register Bufpos	*bp;
X	register char	c = linebuf[curchar];
X
X	if ((index(p_types, c) == 0) ||
X	    (backslashed(linebuf, curchar)))
X		complain((char *) 0);
X	if (dir == FORWARD)
X		ForChar();
X	bp = m_paren(c, dir, YES, NO);
X	if (dir == FORWARD)
X		BackChar();
X	if (bp != 0)
X		SetDot(bp);
X	mp_error();	/* if there is an error the user wants to
X			   know about it */
X}
X
XBufpos *
Xc_indent(incrmt)
X{
X	Bufpos	*bp;
X	int	indent = 0;
X
X	if (bp = m_paren('}', BACKWARD, NO, YES)) {
X		Bufpos	save;
X
X		DOTsave(&save);
X		SetDot(bp);
X		ToIndent();
X		indent = calc_pos(linebuf, curchar);
X		SetDot(&save);
X	}
X	if (incrmt) {
X		if (indent == 0)
X			incrmt = tabstop;
X		else
X			incrmt = (tabstop - (indent%tabstop));
X	}
X	n_indent(indent + incrmt);
X	return bp;
X}
X
X#ifdef CMT_FMT
X
Xchar	CmtFmt[80] = "/*%n%! * %c%!%n */";
X
XComment()
X{
X	FillComment(CmtFmt);
X}
X
X/* Strip leading and trailing white space.  Skip over any imbedded '\r's. */
X
Xprivate
Xstrip_c(from, to)
Xchar	*from,
X	*to;
X{
X	register char	*fr_p = from,
X			*to_p = to,
X			c;
X
X	while (c = *fr_p) {
X		if (c == ' ' || c == '\t' || c == '\r')
X			fr_p++;
X		else
X			break;
X	}
X	while (c = *fr_p) {
X		if (c != '\r')
X			*to_p++ = c;
X		fr_p++;
X	}
X	while (--to_p >= to)
X		if (*to_p != ' ' && *to_p != '\t')
X			break;
X	*++to_p = '\0';
X}
X
Xprivate char	open_c[20],	/* the open comment format string */
X		open_pat[20],	/* the search pattern for open comment */
X		l_header[20],	/* the prefix for each comment line */
X		l_trailer[20],	/* the suffix ... */
X		close_c[20],
X		close_pat[20];
X
Xprivate char	*comment_body[] = {
X 	open_c,
X	l_header,
X	l_trailer,
X	close_c
X};
X					
Xprivate int	nlflags;
X
X/* Fill in the data structures above from the format string.  Don't return
X   if there's trouble. */
X
Xprivate
Xparse_cmt_fmt(str)
Xchar	*str;
X{
X	register char	*fmtp = str;
X	register char	**c_body = comment_body,
X			*body_p = *c_body;
X	int	c,
X	 	newlines = 1;
X
X	/* pick apart the comment string */
X	while (c = *fmtp++) {
X		if (c != '%') {
X			*body_p++ = c;
X			continue;
X		}
X		switch(c = *fmtp++) {
X		case 'n':
X			if (newlines == 2 || newlines == 3)
X				complain("%n not allowed in line header or trailer: %s",
X				  fmtp - 2);
X			nlflags += newlines;
X			*body_p++ = '\r';
X			break;
X		case 't':
X			*body_p++ = '\t';
X			break;
X		case '%':
X			*body_p++ = '%';
X			break;
X		case '!':
X		case 'c':
X			newlines++;
X			*body_p++ = '\0';
X			body_p = *++c_body;
X			break;
X		default:
X			complain("[Unknown comment escape: %%%c]", c);
X			/* VARARGS */
X			break;
X		}
X	}
X	*body_p = '\0';
X	/* make search patterns */
X	strip_c(open_c, open_pat);
X	strip_c(close_c, close_pat);
X}
X
X#define NL_IN_OPEN_C  ((nlflags % 4) == 1)
X#define NL_IN_CLOSE_C (nlflags >= 4)
X
XFillComment(format)
Xchar	*format;
X{
X	int	saveRMargin,
X		indent_pos,
X		close_at_dot = 0,
X		slen,
X		header_len,
X		trailer_len;
X	register char	*cp;
X	static char	inside_err[] = "[Must be between %s and %s to re-format]";
X	Bufpos	open_c_pt,
X		close_c_pt,
X		tmp_bp,
X		*match_o,
X		*match_c;
X	Mark	*entry_mark,
X		*open_c_mark,
X		*savedot;
X
X	parse_cmt_fmt(format);
X	/* figure out if we're "inside" a comment */
X 	if ((match_o = dosearch(open_pat, BACKWARD, 0)) == 0)
X		/* VARARGS */
X		complain("No opening %s to match to.", open_pat);
X	open_c_pt = *match_o;
X	if ((match_c = dosearch(close_pat, BACKWARD, NO)) != 0 &&
X	    inorder(open_c_pt.p_line, open_c_pt.p_char,
X		    match_c->p_line, match_c->p_char))
X	  	complain(inside_err, open_pat, close_pat);
X	if ((match_o = dosearch(open_pat, FORWARD, NO)) != 0) {
X		tmp_bp = *match_o;
X		match_o = &tmp_bp;
X	} 
X	if ((match_c = dosearch(close_pat, FORWARD, 0)) != (Bufpos *) 0)
X		close_c_pt = *match_c;
X
X	/* Here's where we figure out whether to format from dot or from
X	   the close comment.  Note that we've already searched backwards to
X	   find the open comment symbol for the comment we are formatting.
X	   The open symbol mentioned below refers to the possible existence
X	   of the next comment.  There are 5 cases:
X		1) no open or close symbol		==> dot
X		2) open, but no close symbol		==> dot
X		3) close, but no open			==> close
X		4) open, close are inorder		==> dot
X		5) open, close are not inorder		==> close */
X
X
X	if (match_o == (Bufpos *) 0) {
X		if (match_c == (Bufpos *) 0)
X			close_at_dot++;
X	} else if (match_c == (Bufpos *) 0)
X		close_at_dot++;
X	else if (inorder(match_o->p_line, match_o->p_char,
X		 match_c->p_line, match_c->p_char))
X		close_at_dot++;
X
X	if (close_at_dot) {
X		close_c_pt.p_line = curline;
X		close_c_pt.p_char = curchar;
X	} else {
X		SetDot(match_c);
X	}
X	SetDot(&open_c_pt);
X	open_c_mark = MakeMark(curline, curchar, FLOATER);
X	indent_pos = calc_pos(linebuf, curchar);
X	/* search for a close comment; delete it if it exits */
X	SetDot(&close_c_pt);
X	if (close_at_dot == 0) {
X		slen = strlen(close_pat);
X		while (slen--)
X			DelPChar();
X	}
X	entry_mark = MakeMark(curline, curchar, FLOATER);
X	ToMark(open_c_mark);
X	/* always separate the comment body from anything preceeding it */
X	LineInsert(1);
X	DelWtSpace();
X	Bol();
X	for (cp = open_c; *cp; cp++) {
X		if (*cp == '\r') {
X			if (!eolp())
X				LineInsert(1);
X			else
X				line_move(FORWARD, NO);
X		} else if (*cp == ' ' || *cp == '\t') {
X			if (linebuf[curchar] != *cp)
X				Insert(*cp);
X		} else
X			/* Since we matched the open comment string on this
X			   line, we don't need to worry about crossing line
X			   boundaries. */
X			curchar++;
X	}
X	savedot = MakeMark(curline, curchar, FLOATER);
X
X	/* We need to strip the line header pattern of leading white space
X	   since we need to match the line after all of its leading
X	   whitespace is gone. */
X	for (cp = l_header; *cp && (isspace(*cp)); cp++)
X		;
X	header_len = strlen(cp);
X	trailer_len = strlen(l_trailer);
X
X	/* Strip each comment line of the open and close comment strings
X	   before reformatting it. */
X
X	do {
X		Bol();
X		DelWtSpace();
X		if (header_len && !strncmp(linebuf, cp, header_len))
X			DoTimes(DelNChar(), header_len);
X		if (trailer_len) {
X			Eol();
X			if ((curchar > trailer_len) &&
X			    (!strncmp(&linebuf[curchar - trailer_len],
X				      l_trailer, trailer_len)))
X				DoTimes(DelPChar(), trailer_len);
X		}
X		if (curline->l_next != 0)
X			line_move(FORWARD, NO);
X		else
X			break;
X	} while (curline != entry_mark->m_line->l_next);
X
X	DoSetMark(savedot->m_line, savedot->m_char);
X	ToMark(entry_mark);
X	saveRMargin = RMargin;
X	RMargin = saveRMargin - strlen(l_header) -
X		  strlen(l_trailer) - indent_pos + 2;
X	/* do not use the left margin */
X	exp_p = NO;
X	do_rfill();
X	RMargin = saveRMargin;
X	/* get back to the start of the comment */
X	PopMark(); 
X	do {
X		if (curline == open_c_mark->m_line->l_next) {
X			;
X		} else {
X			n_indent(indent_pos);
X			ins_str(l_header, NO);
X		}
X		Eol();
X		if (!NL_IN_CLOSE_C && (curline == entry_mark->m_line))
X			;
X		else
X			ins_str(l_trailer, NO);
X		if (curline->l_next != 0)
X			line_move(FORWARD, NO);
X		else 
X			break;
X	} while (curline != entry_mark->m_line->l_next);
X	/* handle the close comment symbol */
X	if (curline == entry_mark->m_line->l_next) {
X		line_move(BACKWARD, NO);
X		Eol();
X	}
X	DelWtSpace();
X	/* if the addition of the close symbol would cause the line to be
X	   too long, put the close symbol on the next line. */
X	if (strlen(close_c) + calc_pos(linebuf, curchar) > RMargin) {
X		LineInsert(1);
X		n_indent(indent_pos);
X	}
X	for (cp = close_c; *cp; cp++) {
X		if (*cp == '\r') {
X			LineInsert(1);
X			n_indent(indent_pos);
X		} else
X			Insert(*cp);
X	}
X	ToMark(open_c_mark);
X	Eol();
X	exp_p = NO;
X	DelNChar();
X}
X
X#endif CMT_FMT
X
@//E*O*F c.c//
if test 13187 -ne "`wc -c <'c.c'`"; then
    echo shar: error transmitting "'c.c'" '(should have been 13187 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'ctype.c'" '(3709 characters)'
if test -f 'ctype.c' ; then 
  echo shar: will not over-write existing file "'ctype.c'"
else
sed 's/^X//' >ctype.c <<'@//E*O*F ctype.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
X * provided to you without charge, and with no warranty.  You may give  *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files.                                           *
X ************************************************************************/
X
X#include "jove.h"
X#include "ctype.h"
X
Xint	SyntaxTable = FUNDAMENTAL;	/* Current table to use. */
X
Xchar CharTable[NMAJORS][128] = {
X{	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_P,	_P,	_P,	_P,	_P,	_P,	_P,	_P,
X	_Op|_P,	_Cl|_P,	_P,	_P,	_P,	_P,	_P,	_P,
X	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,
X	_W|_N,	_W|_N,	_P,	_P,	_P,	_P,	_P,	_P,
X	_P,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,
X	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,
X	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,
X	_W|_U,	_W|_U,	_W|_U,	_Op|_P,	_P,	_Cl|_P,	_P,	_P,
X	_P,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,
X	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,
X	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,
X	_W|_L,	_W|_L,	_W|_L,	_Op|_P,	_P,	_Cl|_P,	_P,	_C	},
X
X{	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_P,	_P,	_P,	_P,	_P,	_P,	_P,	_P|_W,
X	_Op|_P,	_Cl|_P,	_P,	_P,	_P,	_P,	_P,	_P,
X	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,
X	_W|_N,	_W|_N,	_P,	_P,	_P,	_P,	_P,	_P,
X	_P,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,
X	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,
X	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,
X	_W|_U,	_W|_U,	_W|_U,	_Op|_P,	_P,	_Cl|_P,	_P,	_P,
X	_P,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,
X	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,
X	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,
X	_W|_L,	_W|_L,	_W|_L,	_Op|_P,	_P,	_Cl|_P,	_P,	_C	},
X
X{	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_P,	_P,	_P,	_P,	_P|_W,	_P,	_P,	_P,
X	_Op|_P,	_Cl|_P,	_P,	_P,	_P,	_P,	_P,	_P,
X	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,
X	_W|_N,	_W|_N,	_P,	_P,	_P,	_P,	_P,	_P,
X	_P,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,
X	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,
X	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,
X	_W|_U,	_W|_U,	_W|_U,	_Op|_P,	_P,	_Cl|_P,	_P,	_P|_W,
X	_P,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,
X	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,
X	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,
X	_W|_L,	_W|_L,	_W|_L,	_Op|_P,	_P,	_Cl|_P,	_P,	_C	
X#ifndef LISP
X}
X#else
X},
X
X{	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
X	_P,	_W|_P,	_P,	_P,	_W|_P,	_W|_P,	_W|_P,	_P,
X	_Op|_P,	_Cl|_P,	_W|_P,	_W|_P,	_P,	_W|_P,	_P,	_P,
X	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,	_W|_N,
X	_W|_N,	_W|_N,	_W|_P,	_P,	_W|_P,	_W|_P,	_W|_P,	_W|_P,
X	_W|_P,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,
X	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,
X	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,	_W|_U,
X	_W|_U,	_W|_U,	_W|_U,	_Op|_P,	_P,	_Cl|_P,	_W|_P,	_W|_P,
X	_P,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,
X	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,
X	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,	_W|_L,
X	_W|_L,	_W|_L,	_W|_L,	_Op|_W|_P,	_W|_P,	_Cl|_W|_P,	_W|_P,	_W|_C	},
X#endif
X};
X
Xismword(c)
X{
X	return ((CharTable[curbuf->b_major])[c]&(_W));
X}
@//E*O*F ctype.c//
if test 3709 -ne "`wc -c <'ctype.c'`"; then
    echo shar: error transmitting "'ctype.c'" '(should have been 3709 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'delete.c'" '(6395 characters)'
if test -f 'delete.c' ; then 
  echo shar: will not over-write existing file "'delete.c'"
else
sed 's/^X//' >delete.c <<'@//E*O*F delete.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
X * provided to you without charge, and with no warranty.  You may give  *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files.                                           *
X ************************************************************************/
X
X/* Routines to perform all kinds of deletion.  */
X
X#include "jove.h"
X
X/* Assumes that either line1 or line2 is actual the current line, so it can
X   put its result into linebuf. */
X
Xpatchup(line1, char1, line2, char2)
XLine	*line1,
X	*line2;
Xregister int	char1,
X		char2;
X{
X	if (line1 != line2)
X		ChkWindows(line1, line2);
X	DotTo(line1, char1);
X	modify();
X	linecopy(linebuf, curchar, lcontents(line2) + char2);
X
X	/* The following is a redisplay optimization. */
X	if (line1 != line2 && (char1 == 0 && char2 == 0))
X		line1->l_dline = line2->l_dline;
X
X	DFixMarks(line1, char1, line2, char2);
X	makedirty(curline);
X}
X
X/* Deletes the region by unlinking the lines in the middle,
X   and patching things up.  The unlinked lines are still in
X   order.  */
X
XLine *
Xreg_delete(line1, char1, line2, char2)
XLine	*line1,
X	*line2;
X{
X	register Line	*retline;
X
X	if ((line1 == line2 && char1 == char2) || line2 == 0)
X		complain((char *) 0);
X	(void) fixorder(&line1, &char1, &line2, &char2);
X
X	retline = nbufline();	/* New buffer line */
X
X	(void) ltobuf(line1, genbuf);
X	if (line1 == line2)
X		genbuf[char2] = '\0';
X
X	retline->l_prev = 0;
X	retline->l_dline = putline(&genbuf[char1]);
X	patchup(line1, char1, line2, char2);
X
X	if (line1 == line2)
X		retline->l_next = 0;
X	else {
X		retline->l_next = line1->l_next;
X		(void) ltobuf(line2, genbuf);
X		genbuf[char2] = '\0';
X		line2->l_dline = putline(genbuf);
X		/* Shorten this line */
X	}
X
X	if (line1 != line2) {
X		line1->l_next = line2->l_next;
X		if (line1->l_next)
X			line1->l_next->l_prev = line1;
X		else
X			curbuf->b_last = line1;
X		line2->l_next = 0;
X	}
X
X	return retline;
X}
X
Xlremove(line1, line2)
Xregister Line	*line1,
X		*line2;
X{
X	Line	*next = line1->l_next;
X
X	if (line1 == line2)
X		return;
X	line1->l_next = line2->l_next;
X	if (line1->l_next)
X		line1->l_next->l_prev = line1;
X	else
X		curbuf->b_last = line1;
X	lfreereg(next, line2);	/* Put region at end of free line list. */
X}
X
X/* Delete character forward */
X
XDelNChar()
X{
X	del_char(1);
X}
X
X/* Delete character backward */
X
XDelPChar()
X{
X	if (MinorMode(OverWrite)) {
X		int	count = min(exp, curchar);
X
X		DoTimes(BackChar(), count);
X		LastKeyStruck = ' ';	/* can you say gross? */
X		DoTimes(SelfInsert(), count);
X		DoTimes(BackChar(), count);
X	} else		
X		del_char(0);
X}
X
X/* Delete some characters.  If deleting `forward' then call for_char
X   to the final position otherwise call back_char.  Then delete the
X   region between the two with patchup(). */
X
Xdel_char(forward)
X{
X	Bufpos	before,
X		after;
X	int	killp = (exp_p && abs(exp) > 1);
X
X	DOTsave(&before);
X	(forward) ? ForChar() : BackChar();
X	if (before.p_line == curline && before.p_char == curchar)
X		complain((char *) 0);
X	if (killp)
X		reg_kill(before.p_line, before.p_char, 1);
X	else {
X		DOTsave(&after);
X		(void) fixorder(&before.p_line, &before.p_char, &after.p_line, &after.p_char);
X		patchup(before.p_line, before.p_char, after.p_line, after.p_char);
X		lremove(before.p_line, after.p_line);
X	}
X}
X
X/* This kills a region between point, and line1/char1 and puts it on
X   the kill-ring.  If the last command was one of the kill commands,
X   the region is appended (prepended if backwards) to the last entry.  */
X
Xint	killptr = 0;
XLine	*killbuf[NUMKILLS];
X
Xreg_kill(line2, char2, dot_moved)
XLine	*line2;
X{
X	Line	*nl,
X		*line1 = curline;
X	int	char1 = curchar;
X	int	backwards;
X
X	backwards = !fixorder(&line1, &char1, &line2, &char2);
X	/* This is a kludge!  But it possible for commands that don't
X	   know which direction they are deleting in (e.g., delete
X	   previous word could have been called with a negative argument
X	   in which case, it wouldn't know that it really deleted
X	   forward. */
X
X	if (!dot_moved)
X		backwards = !backwards;
X
X	DotTo(line1, char1);
X
X	nl = reg_delete(line1, char1, line2, char2);
X
X	if (last_cmd != KILLCMD) {
X		killptr = ((killptr + 1) % NUMKILLS);
X		lfreelist(killbuf[killptr]);
X		killbuf[killptr] = nl;
X	} else {
X		Line	*lastln = lastline(nl);
X
X		if (backwards)
X			(void) DoYank(nl, 0, lastln, length(lastln), killbuf[killptr], 0, (Buffer *) 0);
X		else {
X			Line	*olastln = lastline(killbuf[killptr]);
X
X			(void) DoYank(nl, 0, lastln, length(lastln), olastln, length(olastln), (Buffer *) 0);
X		}
X	}
X	this_cmd = KILLCMD;
X}
X
XDelReg()
X{
X	register Mark	*mp = CurMark();
X
X	reg_kill(mp->m_line, mp->m_char, 0);
X}
X
X/* Save a region.  A pretend kill. */
X
XCopyRegion()
X{
X	register Line	*nl;
X	register Mark	*mp;
X	register int	status;
X
X	mp = CurMark();
X	if (mp->m_line == curline && mp->m_char == curchar)
X		complain((char *) 0);
X
X	killptr = ((killptr + 1) % NUMKILLS);
X	if (killbuf[killptr])
X		lfreelist(killbuf[killptr]);
X	nl = killbuf[killptr] = nbufline();
X	SavLine(nl, NullStr);
X	nl->l_next = nl->l_prev = 0;
X
X	status = inorder(mp->m_line, mp->m_char, curline, curchar);
X	if (status == -1)
X		return;
X
X	if (status)
X		(void) DoYank(mp->m_line, mp->m_char, curline, curchar,
X				nl, 0, (Buffer *) 0);
X	else
X		(void) DoYank(curline, curchar, mp->m_line, mp->m_char,
X				nl, 0, (Buffer *) 0);
X}
X
XDelWtSpace()
X{
X	register char	*ep = &linebuf[curchar],
X			*sp = &linebuf[curchar];
X
X	while (*ep == ' ' || *ep == '\t')
X		ep++;
X	while (sp > linebuf && *(sp - 1) == ' ' || *(sp - 1) == '\t')
X		sp--;
X	if (sp != ep) {
X		curchar = sp - linebuf;
X		DFixMarks(curline, curchar, curline, curchar + (ep - sp));
X		strcpy(sp, ep);
X		makedirty(curline);
X		modify();
X	}
X}
X
XDelBlnkLines()
X{
X	register Mark	*dot;
X	int	all;
X
X	exp = 1;
X	if (!blnkp(&linebuf[curchar]))
X		return;
X	dot = MakeMark(curline, curchar, FLOATER);
X	all = !blnkp(linebuf);
X	while (blnkp(linebuf) && curline->l_prev)
X		SetLine(curline->l_prev);
X	all |= (firstp(curline));
X	Eol();
X	DelWtSpace();
X	line_move(FORWARD, NO);
X	while (blnkp(linebuf) && !eobp()) {
X		DelWtSpace();
X		DelNChar();
X	}
X	if (!all && !eobp())
X		OpenLine();
X	ToMark(dot);
X	DelMark(dot);
X}
X
XDelNWord()
X{
X	dword(1);
X}
X
XDelPWord()
X{
X	dword(0);
X}
X
Xdword(forward)
X{
X	Bufpos	savedot;
X
X	DOTsave(&savedot);
X	forward ? ForWord() : BackWord();
X	reg_kill(savedot.p_line, savedot.p_char, 1);
X}
@//E*O*F delete.c//
if test 6395 -ne "`wc -c <'delete.c'`"; then
    echo shar: error transmitting "'delete.c'" '(should have been 6395 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'disp.c'" '(24166 characters)'
if test -f 'disp.c' ; then 
  echo shar: will not over-write existing file "'disp.c'"
else
sed 's/^X//' >disp.c <<'@//E*O*F disp.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
X * provided to you without charge, and with no warranty.  You may give  *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files.                                           *
X ************************************************************************/
X
X#include "jove.h"
X#include "ctype.h"
X#include "termcap.h"
X
X#include <varargs.h>
X#include <signal.h>
X#include <sys/stat.h>
X
X/* Kludge windows gets called by the routines that delete lines from the
X   buffer.  If the w->w_line or w->w_top are deleted and this procedure
X   is not called, the redisplay routine will barf. */
X
XChkWindows(line1, line2)
XLine	*line1;
Xregister Line	*line2;
X{
X	register Window	*w = fwind;
X	register Line	*lp;
X
X	do {
X		for (lp = line1->l_next; lp != line2->l_next; lp = lp->l_next) {
X			if (lp == w->w_top)
X				w->w_flags |= W_TOPGONE;
X			if (lp == w->w_line)
X				w->w_flags |= W_CURGONE;
X		}
X		w = w->w_next;
X	} while (w != fwind);
X}
X
Xextern int	RingBell;
X
Xredisplay()
X{
X	register Window	*w = fwind;
X	int	lineno,
X		done_ID = 0,
X		i;
X	register struct scrimage	*des_p,
X					*phys_p;
X
X	curwind->w_line = curwind->w_bufp->b_dot;
X	curwind->w_char = curwind->w_bufp->b_char;
X
X	if (InputPending = charp())
X		return;
X
X#ifdef JOB_CONTROL
X	if (UpdFreq)
X		sighold(SIGALRM);
X#endif
X	if (RingBell) {
X		dobell(1);
X		RingBell = 0;
X	}
X	if (UpdMesg)
X		DrawMesg(YES);
X
X	for (lineno = 0, w = fwind; lineno < ILI; w = w->w_next) {
X		UpdWindow(w, lineno);
X		lineno += w->w_height;
X	}
X
X	des_p = DesiredScreen;
X	phys_p = PhysScreen;
X	for (i = 0; i < ILI; i++, des_p++, phys_p++) {
X		if (!done_ID && (des_p->s_id != phys_p->s_id)) {
X			DoIDline(i);
X			done_ID++;
X		}
X		if ((des_p->s_flags & (DIRTY | L_MOD)) ||
X		    (des_p->s_id != phys_p->s_id) ||
X		    (des_p->s_vln != phys_p->s_vln) ||
X		    (des_p->s_offset != phys_p->s_offset))
X			UpdLine(i);
X		if (InputPending)
X			goto ret;
X	}
X
X	UpdModLine = 0;
X
X	if (Asking) {
X		Placur(LI - 1, min(CO - 2, calc_pos(mesgbuf, Asking)));
X			/* Nice kludge */
X		flusho();
X	} else
X		GotoDot();
Xret:
X#ifdef JOB_CONTROL
X	if (UpdFreq)
X		sigrelse(SIGALRM);
X#else
X	;	/* yuck */
X#endif
X
X}
X
Xdobell(n)
X{
X	while (--n >= 0) {
X		if (VisBell && VB)
X			putstr(VB);
X		else
X#ifdef SYSV	/* release 2, at least */
X			putpad("$<20>\007", 1) ;
X#else
X			putpad("20\007", 1);
X#endif SYSV
X	}
X	flusho();
X}
X
X/* find_pos() returns the position on the line, that c_char represents
X   in line. */
X
Xfind_pos(line, c_char)
XLine	*line;
X{
X	return calc_pos(lcontents(line), c_char);
X}
X
Xcalc_pos(lp, c_char)
Xregister char	*lp;
Xregister int	c_char;
X{
X	register int	pos = 0;
X	register int	c;
X
X	while ((--c_char >= 0) && ((c = *lp++) & 0177) != 0) {
X		if (c == '\t')
X			pos += (tabstop - (pos % tabstop));
X		else if (isctrl(c))
X			pos += 2;
X		else
X			pos++;
X 	}
X	return pos;
X}
X
Xint	UpdModLine = 0,
X	UpdMesg = 0,
X	CanScroll = 0;
X
XDoIDline(start)
X{
X	register struct scrimage	*des_p = &DesiredScreen[start];
X	struct scrimage	*phys_p = &PhysScreen[start];
X	register int	i,
X			j;
X
X	/* Some changes have been made.  Try for insert or delete lines.
X	   If either case has happened, Addlines and/or DelLines will do
X	   necessary scrolling, also CONVERTING PhysScreen to account for the
X	   physical changes.  The comparison continues from where the
X	   insertion/deletion takes place; this doesn't happen very often,
X	   usually it happens with more than one window with the same
X	   buffer. */
X
X	if (!CanScroll)
X		return;		/* We should never have been called! */
X
X	for (i = start; i < ILI; i++, des_p++, phys_p++)
X		if (des_p->s_id != phys_p->s_id)
X			break;
X
X	for (; i < ILI; i++) {
X		for (j = i + 1; j < ILI; j++) {
X			des_p = &DesiredScreen[j];
X			phys_p = &PhysScreen[j];
X			if (des_p->s_id != 0 && des_p->s_id == phys_p->s_id)
X				break;
X			if (des_p->s_id == PhysScreen[i].s_id) {
X				if (des_p->s_id == 0)
X					continue;
X				if (AddLines(i, j - i)) {
X					DoIDline(j);
X					return;
X				}
X				break;
X			}
X			if ((des_p = &DesiredScreen[i])->s_id == phys_p->s_id) {
X				if (des_p->s_id == 0)
X					continue;
X				if (DelLines(i, j - i)) {
X					DoIDline(i);
X					return;
X				}
X				break;
X			}
X		}
X	}
X}
X
X/* Make DesiredScreen reflect what the screen should look like when we are done
X   with the redisplay.  This deals with horizontal scrolling.  Also makes
X   sure the current line of the Window is in the window. */
X
XUpdWindow(w, start)
Xregister Window	*w;
X{
X	Line	*lp;
X	int	i,
X		DotIsHere = 0,
X		upper,		/* Top of window */
X		lower,		/* Bottom of window */
X		ntries = 0;	/* # of tries at updating window. */
X	register struct scrimage	*des_p,
X					*phys_p;
X	Buffer	*bp = w->w_bufp;
X
Xretry:
X	if (w->w_flags & W_CURGONE) {
X		w->w_line = bp->b_dot;
X		w->w_char = bp->b_char;
X	}
X	if (w->w_flags & W_TOPGONE)
X		CentWind(w);	/* Reset topline of screen */
X	w->w_flags &= ~(W_CURGONE|W_TOPGONE);
X	for (i = w->w_height, lp = w->w_top; --i > 0 && lp != 0; lp = lp->l_next)
X		if (lp == w->w_line)
X			break;
X	if (i == 0 || lp == 0) {	/* current line not in window */
X		ntries++;
X		if (ntries == 1) {
X			CalcWind(w);
X			goto retry;
X		} else if (ntries == 2) {
X			w->w_top = w->w_line = w->w_bufp->b_first;
X			printf("\rERROR in redisplay: I got hopelessly lost!");
X			dobell(2);
X			goto retry;
X		} else if (ntries == 3) {
X			printf("\n\rOops, still lost, quitting ...\r\n");
X			finish(1);
X		}
X	}
X
X	upper = start;
X	lower = upper + w->w_height - 1;	/* Don't include modeline */
X	des_p = &DesiredScreen[upper];
X	phys_p = &PhysScreen[upper];
X	for (i = upper, lp = w->w_top; lp != 0 && i < lower; i++, des_p++, phys_p++, lp = lp->l_next) {
X		des_p->s_window = w;
X		des_p->s_lp = lp;
X		des_p->s_id = lp->l_dline & ~DIRTY;
X		des_p->s_flags = isdirty(lp) ? L_MOD : 0;
X		if (w->w_flags & W_NUMLINES)
X			des_p->s_vln = w->w_topnum + (i - upper);
X		else
X			des_p->s_vln = 0;
X
X		if (lp == w->w_line) {
X			int	diff = (w->w_flags & W_NUMLINES) ? 8 : 0,
X				strt_col = phys_p->s_offset,
X				end_col = strt_col + (CO - 2) - diff;
X
X			/* Right now we are displaying from strt_col to
X			   end_col of the buffer line.  These are PRINT
X			   colums, not actual characters. */
X			w->w_dotline = i;
X			w->w_dotcol = find_pos(lp, w->w_char);
X			/* if the new dotcol is out of range, reselect
X			   a horizontal window */
X			if (w->w_dotcol < strt_col || w->w_dotcol >= end_col) {
X				if (w->w_dotcol < ((CO - 2) - diff))
X					strt_col = 0;
X				else
X					strt_col = w->w_dotcol - (CO / 2);
X			}
X			w->w_dotcol += diff;
X			des_p->s_offset = strt_col;
X			DotIsHere++;
X		} else
X			des_p->s_offset = 0;
X	}
X	if (!DotIsHere) {
X		f_mess("DotNotHere is impossible!");
X		finish(1);
X	}
X
X	/* Is structure assignment faster than copy each field seperately */
X	if (i < lower) {
X		static struct scrimage	dirty_plate = { 0, DIRTY, 0, 0, 0, 0 },
X					clean_plate = { 0, 0, 0, 0, 0, 0 };
X
X		for (; i < lower; i++, des_p++, phys_p++)
X			if (phys_p->s_id != 0)
X				*des_p = dirty_plate;
X			else
X				*des_p = clean_plate;
X	}
X
X	des_p->s_window = w;
X	des_p->s_flags = 0;
X	if (((des_p->s_id = (int) w->w_bufp) != phys_p->s_id) || UpdModLine)
X		des_p->s_flags = MODELINE | DIRTY;
X}
X
X/* Write whatever is in mesgbuf (maybe we are Asking, or just printed
X   a message).  Turns off the UpdateMesg line flag. */
X
XDrawMesg(abortable)
X{
X	if (charp())
X		return;
X	i_set(ILI, 0);
X	if (swrite(mesgbuf, NIL, abortable)) {
X		cl_eol();
X		UpdMesg = 0;
X	}
X	flusho();
X}
X
X/* Goto the current position in the current window.  Presumably redisplay()
X   has already been called, and curwind->{w_dotline,w_dotcol} have been set
X   correctly. */
X
XGotoDot()
X{
X	if (InputPending)
X		return;
X	Placur(curwind->w_dotline, curwind->w_dotcol -
X				PhysScreen[curwind->w_dotline].s_offset);
X	flusho();
X}
X
Xprivate
XUntilEqual(start)
Xregister int	start;
X{
X	register struct scrimage	*des_p = &DesiredScreen[start],
X					*phys_p = &PhysScreen[start];
X
X	while ((start < ILI) && (des_p->s_id != phys_p->s_id)) {
X		des_p++;
X		phys_p++;
X		start++;
X	}
X
X	return start;
X}
X
X/* Calls the routine to do the physical changes, and changes PhysScreen to
X   reflect those changes. */
X
XAddLines(at, num)
Xregister int	at,
X		num;
X{
X	register  int	i;
X	int	bottom = UntilEqual(at + num);
X
X	if (num == 0 || num >= ((bottom - 1) - at))
X		return 0;	/* We did nothing */
X	v_ins_line(num, at, bottom - 1);
X
X	/* Now change PhysScreen to account for the physical change. */
X
X	for (i = bottom - 1; i - num >= at; i--)
X		PhysScreen[i] = PhysScreen[i - num];
X	for (i = 0; i < num; i++)
X		PhysScreen[at + i].s_id = 0;
X	return 1;	/* We did something. */
X}
X
XDelLines(at, num)
Xregister int	at,
X		num;
X{
X	register int	i;
X	int	bottom = UntilEqual(at + num);
X
X	if (num == 0 || num >= ((bottom - 1) - at))
X		return 0;
X	v_del_line(num, at, bottom - 1);
X
X	for (i = at; num + i < bottom; i++)
X		PhysScreen[i] = PhysScreen[num + i];
X	for (i = bottom - num; i < bottom; i++)
X		PhysScreen[i].s_id = 0;
X	return 1;
X}
X
X/* Update line linenum in window w.  Only set PhysScreen to DesiredScreen
X   if the swrite or cl_eol works, that is nothing is interupted by 
X   characters typed. */ 
X
XUpdLine(linenum)
Xregister int	linenum;
X{
X	register struct scrimage	*des_p = &DesiredScreen[linenum];
X	register Window	*w = des_p->s_window;
X
X	i_set(linenum, 0);
X	if (des_p->s_flags & MODELINE)
X		ModeLine(w);
X	else if (des_p->s_id) {
X		des_p->s_lp->l_dline &= ~DIRTY;
X		des_p->s_flags &= ~(DIRTY | L_MOD);
X#ifdef ID_CHAR
X		if (!UseIC && (w->w_flags & W_NUMLINES))
X#else
X		if (w->w_flags & W_NUMLINES)
X#endif
X			(void) swrite(sprint("%6d  ", des_p->s_vln), NIL, YES);
X
X#ifdef ID_CHAR
X		if (UseIC) {
X			char	outbuf[256],
X				*lptr;
X			int	fromcol = (w->w_flags & W_NUMLINES) ? 8 : 0;
X
X			if (w->w_flags & W_NUMLINES)
X				sprintf(outbuf, "%6d  ", des_p->s_vln);
X			lptr = lcontents(des_p->s_lp);
X			DeTab(des_p->s_offset, lptr, outbuf + fromcol,
X				(sizeof outbuf) - 1 - fromcol,
X				des_p->s_window->w_flags & W_VISSPACE);
X			if (IDchar(outbuf, linenum, 0))
X				PhysScreen[linenum] = *des_p;
X			else if (i_set(linenum, 0), swrite(outbuf, NIL, YES))
X				do_cl_eol(linenum);
X			else
X				PhysScreen[linenum].s_id = -1;
X		} else
X#endif ID_CHAR
X		    if (BufSwrite(linenum))
X			do_cl_eol(linenum);
X		else
X			PhysScreen[linenum].s_id = -1;
X	} else if (PhysScreen[linenum].s_id)	/* Not the same ... make sure */
X		do_cl_eol(linenum);
X}
X
Xdo_cl_eol(linenum)
Xregister int	linenum;
X{
X	cl_eol();
X	PhysScreen[linenum] = DesiredScreen[linenum];
X}
X
X#ifdef ID_CHAR
X
X/* From here to the end of the file is code that tries to utilize the
X   insert/delete character feature on some terminals.  It is very confusing
X   and not so well written code, AND there is a lot of it.  You may want
X   to use the space for something else. */
X
Xextern struct screenline	*Screen;
Xint	IN_INSmode = 0;
X
Xint	UseIC;
X
Xint	DClen,
X	MDClen,
X	IClen,
X	MIClen,
X	IMlen,
X	CElen;
X
Xdisp_opt_init()
X{
X	DClen = DC ? strlen(DC) : 0;
X	MDClen = M_DC ? strlen(M_DC) : 9999;
X	IClen = IC ? strlen(IC) : 0;
X	MIClen = M_IC ? strlen(M_IC) : 9999;
X	IMlen = IM ? strlen(IM) : 0;
X	CElen = CE ? strlen(CE) : 0;
X
X	UseIC = (IC || IM || M_IC);
X}
X
XINSmode(on)
X{
X	if (on && !IN_INSmode) {
X		putpad(IM, 1);
X		IN_INSmode++;
X	} else if (!on && IN_INSmode) {
X		putpad(EI, 1);
X		IN_INSmode = 0;
X	}
X}
X
Xprivate
XDeTab(s_offset, buf, outbuf, limit, visspace)
Xregister char	*buf;
Xchar	*outbuf;
X{
X	register char	*phys_p = outbuf,
X			c;
X	register int	pos = 0;
X	char		*limitp = &outbuf[limit];
X
X#define OkayOut(ch)	if ((pos++ >= s_offset) && (phys_p < limitp))\
X				*phys_p++ = ch;\
X			else
X
X	while (c = *buf++) {
X		if (c == '\t') {
X			int	nchars = (tabstop - (pos % tabstop));
X
X			if (visspace) {
X				OkayOut('>');
X				--nchars;
X			}
X			while (--nchars >= 0)
X				OkayOut(' ');
X
X		} else if (isctrl(c)) {
X			OkayOut('^');
X			OkayOut(c == 0177 ? '?' : c + '@');
X		} else {
X			if (visspace && c == ' ')
X				c = '_';
X			OkayOut(c);
X		}
X		if (pos - s_offset >= CO) {
X			phys_p = &outbuf[CO - 1];
X			*phys_p++ = '!';
X			break;
X		}			
X	}
X	*phys_p = 0;
X}
X
X/* ID character routines full of special cases and other fun stuff like that.
X   It actually works though ... 
X
X  	Returns Non-Zero if you are finished (no differences left). */
X
Xprivate
XIDchar(new, lineno, col)
Xregister char	*new;
X{
X	register int	i;
X	int	j,
X		oldlen,
X		NumSaved;
X	register struct screenline	*sline = &Screen[lineno];
X
X	oldlen = sline->s_length - sline->s_line;
X
X	for (i = col; i < oldlen && new[i] != 0; i++)
X		if (sline->s_line[i] != new[i])
X			break;
X	if (new[i] == 0 || i == oldlen)
X		return (new[i] == 0 && i == oldlen);
X
X	for (j = i + 1; j < oldlen && new[j]; j++) {
X		if (new[j] == sline->s_line[i]) {
X			NumSaved = IDcomp(new + j, sline->s_line + i,
X					strlen(new)) + NumSimilar(new + i,
X						sline->s_line + i, j - i);
X			if (OkayInsert(NumSaved, j - i)) {
X				InsChar(lineno, i, j - i, new);
X				return(IDchar(new, lineno, j));
X			}
X		}
X	}
X
X	for (j = i + 1; j < oldlen && new[i]; j++) {
X		if (new[i] == sline->s_line[j]) {
X			NumSaved = IDcomp(new + i, sline->s_line + j,
X					oldlen - j);
X			if (OkayDelete(NumSaved, j - i, new[oldlen] == 0)) {
X				DelChar(lineno, i, j - i);
X				return(IDchar(new, lineno, j));
X			}
X		}
X	}
X	return 0;
X}
X
Xprivate
XNumSimilar(s, t, n)
Xregister char	*s,
X		*t;
X{
X	register int	num = 0;
X
X	while (n--)
X		if (*s++ == *t++)
X			num++;
X	return num;
X}
X
Xprivate
XIDcomp(s, t, len)
Xregister char	*s,
X		*t;
X{
X	register int	i;
X	int	num = 0,
X		nonspace = 0;
X	char	c;
X
X	for (i = 0; i < len; i++) {
X		if ((c = *s++) != *t++)
X			break;
X		if (c != ' ')
X			nonspace++;
X		if (nonspace)
X			num++;
X	}
X
X	return num;
X}
X
Xprivate
XOkayDelete(Saved, num, samelength)
X{
X	/* If the old and the new are the same length, then we don't
X	 * have to clear to end of line.  We take that into consideration.
X	 */
X	return ((Saved + (!samelength ? CElen : 0))
X		> min(MDClen, DClen * num));
X}
X
Xprivate
XOkayInsert(Saved, num)
X{
X	register int	n = 0;
X
X	if (IC)		/* Per character prefixes */
X		n = min(num * IClen, MIClen);
X
X	if (IM && !IN_INSmode) {	
X		/* Good terminal.  Fewer characters in this case */
X		n += IMlen;
X	}
X
X	n += num;	/* The characters themselves */
X
X	return Saved > n;
X}
X
Xextern int	CapCol;
Xextern char	*cursend;
Xextern struct screenline	*Curline;
X
Xprivate
XDelChar(lineno, col, num)
X{
X	register char	*from,
X			*to;
X	register int	i;
X	struct screenline *sp = (&Screen[lineno]);
X
X	Placur(lineno, col);
X	if (M_DC && num > 1) {
X		char	minibuf[16];
X
X		sprintf(minibuf, M_DC, num);
X		putpad(minibuf, num);
X	} else {
X		for (i = num; --i >= 0; )
X			putpad(DC, 1);
X	}
X
X	to = sp->s_line + col;
X	from = to + num;
X
X	byte_copy(from, to, sp->s_length - from + 1);
X	clrline(sp->s_length - num, sp->s_length);
X	sp->s_length -= num;
X}
X
Xprivate
XInsChar(lineno, col, num, new)
Xchar	*new;
X{
X	register char	*sp1,
X			*sp2,	/* To push over the array. */
X			*sp3;	/* Last character to push over. */
X	int	i;
X
X	i_set(lineno, 0);
X	sp2 = Curline->s_length + num;
X
X	if (sp2 >= cursend) {
X		i_set(lineno, CO - num - 1);
X		cl_eol();
X		sp2 = cursend - 1;
X	}
X	Curline->s_length = sp2;
X	sp1 = sp2 - num;
X	sp3 = Curline->s_line + col;
X
X	while (sp1 >= sp3)
X		*sp2-- = *sp1--;
X
X	new += col;
X	byte_copy(new, sp3, num);
X	/* The internal screen is correct, and now we have to do
X	   the physical stuff. */
X
X	Placur(lineno, col);
X	if (IM) {
X		if (!IN_INSmode)
X			INSmode(1);
X	} else if (M_IC && num > 1) {
X		char	minibuf[16];
X
X		sprintf(minibuf, M_IC, num);
X		putpad(minibuf, num);
X	} else if (IC) {
X		for (i = 0; i < num; i++)
X			putpad(IC, 1);
X	}
X	for (i = 0; i < num; i++) {
X		putchar(new[i]);
X		if (IN_INSmode)
X			putpad(IP, 1);
X	}
X	CapCol += num;
X}
X
X#endif ID_CHAR
X
X/* chkmail() returns nonzero if there is new mail since the
X   last time we checked. */
X
Xchar	Mailbox[128];	/* initialized in main */
Xint	MailInt = 60;	/* check no more often than 60 seconds */
X#ifdef BIFF
Xint	BiffChk = NO;	/* whether or not to turn off biff while in JOVE */
X#endif
X
Xchkmail(force)
X{
X	time_t	now;
X	static time_t	last_chk = 0;
X	static int	value = FALSE;
X	static off_t	last_size = 0;
X	struct stat	stbuf;
X	int	last_val;
X	extern time_t	time0;
X
X	time(&now);
X	if (!force && (now < last_chk + MailInt))
X		return value;
X	if (stat(Mailbox, &stbuf) < 0)
X		return FALSE;
X	last_val = value;
X	value = ((stbuf.st_mtime > time0) &&
X		 (stbuf.st_size > 0) &&
X		 (stbuf.st_size > last_size) &&
X		 (stbuf.st_mtime + 5 > stbuf.st_atime));
X	last_chk = now;
X	last_size = stbuf.st_size;
X	if (value == TRUE && value != last_val)
X		dobell(3);
X	return value;
X}
X
X/* Print the mode line. */
X
Xprivate char	*mode_p,
X		*mend_p;
Xint	BriteMode = 1;		/* modeline should standout */
X
Xprivate
Xmode_app(str)
Xregister char	*str;
X{
X	if (mode_p >= mend_p)
X		return;
X	while ((mode_p < mend_p) && (*mode_p++ = *str++))
X		;
X	mode_p--;	/* back over the null */
X}
X
Xchar	ModeFmt[120] = "%3c %[%sJOVE (%M)   Buffer: %b  \"%f\" %]%s%m*- %((%t)%s%)%e";
X
XModeLine(w)
Xregister Window	*w;
X{
X	extern int	i_line;
X	int	n,
X		ign_some = 0;
X	char	line[132],
X		*fmt = ModeFmt,
X		tmp[16],
X		fillc,
X		c;
X	register Buffer	*thisbuf = w->w_bufp;
X	register Buffer *bp;
X
X	mode_p = line;
X	mend_p = &line[(sizeof line) - 1];
X
X	if (BriteMode != 0 && SO == 0)
X		BriteMode = 0;
X	fillc = BriteMode ? ' ' : '-';
X
X	while (c = *fmt++) {
X		if (c != '%') {
X			if (c == '\\')
X				if ((c = *fmt++) == '\0')
X					break;
X			if (!ign_some)
X				*mode_p++ = c;
X			continue;
X		}
X		if ((c = *fmt++) == '\0')	/* char after the '%' */
X			break;
X		if (ign_some && c != ')')
X			continue;
X		n = 1;
X		if (c >= '0' && c <= '9') {
X			n = 0;
X			while (c >= '0' && c <= '9') {
X				n = n * 10 + (c - '0');
X				c = *fmt++;
X			}
X		}
X		switch (c) {
X		case '(':
X			if (w->w_next != fwind)	/* Not bottom window. */
X				ign_some++;
X			break;
X
X		case ')':
X			ign_some = 0;
X			break;
X
X		case 'c':
X			while (--n >= 0)
X				*mode_p++ = fillc;
X			break;
X
X		case '[':
X		case ']':
X		    {
X		    	char	*strs = (c == '[') ? "[[[[[[[[[[" : "]]]]]]]]]]";
X
X		    	mode_app(strs + 10 - RecDepth);
X			break;
X		    }
X			
X		case 's':
X			if (mode_p[-1] == ' ')
X				continue;
X			*mode_p++ = ' ';
X			break;
X
X		case 'M':
X		    {
X		    	static char	*mmodes[] = {
X				"Fundamental ",
X				"Text ",
X				"C ",
X#ifdef LISP
X				"Lisp ",
X#endif
X				0
X			};
X
X		    	mode_app(mmodes[thisbuf->b_major]);
X
X			if (BufMinorMode(thisbuf, Fill))
X				mode_app("Fill ");
X			if (BufMinorMode(thisbuf, Abbrev))
X				mode_app("Abbrev ");
X			if (BufMinorMode(thisbuf, OverWrite))
X				mode_app("OvrWt ");
X			if (BufMinorMode(thisbuf, Indent))
X				mode_app("AI ");
X			if (KeyMacro.m_flags & DEFINE)
X				mode_app("Def ");
X			mode_p--;	/* Back over the extra space. */
X			break;
X		    }
X
X		case 'b':
X			mode_app(thisbuf->b_name);
X			break;
X
X		case 'f':
X		case 'F':
X			if (thisbuf->b_fname == 0)
X				mode_app("[No file]");
X			else {
X				if (c == 'f')
X					mode_app(pr_name(thisbuf->b_fname));
X				else
X					mode_app(basename(thisbuf->b_fname));
X			}
X			break;
X
X
X		case 'n':
X			for (bp = world, n = 1; bp != 0; bp = bp->b_next, n++)
X				if (bp == thisbuf)
X					break;
X
X			sprintf(tmp, "%d", n);
X			mode_app(tmp);
X			break;
X
X		case 'm':
X			if (IsModified(w->w_bufp))
X				*mode_p++ = fmt[0];
X			else
X				*mode_p++ = fmt[1];
X			fmt += 2;	/* skip two characters */
X			break;
X
X		case 't':
X		    {
X			char	timestr[12];
X
X		    	mode_app(get_time((time_t *) 0, timestr, 11, 16));
X			break;
X		    }
X
X#ifdef LOAD_AV
X		case 'l':
X		    {
X			double	theavg;
X		    	char	minibuf[10];
X
X		    	get_la(&theavg);
X		    	theavg += .005;	/* round to nearest .01 */
X		    	sprintf(minibuf, "%d.%02d",
X			       (int) theavg,
X			       (int)((theavg - (int) theavg) * 100));
X		    	mode_app(minibuf);
X		    }
X		    break;
X#endif
X
X		case 'C':	/* check mail here */
X			if (chkmail(NO))
X				mode_app("[New mail]");
X			break;
X
X#ifdef CHDIR
X		case 'd':	/* print working directory */
X			mode_app(pr_name(pwd()));
X			break;
X#endif
X			
X		case 'e':
X		    {
X			/* 2 space pad pluss padding for magic cookies */
X			char	*last_p = &line[CO - 2 - (2 * SG)];
X
X			while (mode_p < last_p)
X				*mode_p++ = fillc;
X
X		    	goto outahere;		/* %e means we're done! */
X		    }
X		}
X	}
X
Xoutahere:
X	*mode_p = 0;
X
X	/* Highlight mode line. */
X	if (BriteMode) {
X#ifdef ID_CHAR
X		if (IN_INSmode)
X			INSmode(0);
X#endif
X		putpad(SO, 1);
X	}
X	if (swrite(line, BriteMode, YES))
X		do_cl_eol(i_line);
X	if (BriteMode)
X		putpad(SE, 1);
X}
X
XRedrawDisplay()
X{
X	Line	*newtop = prev_line((curwind->w_line = curline), exp_p ?
X				exp : HALF(curwind));
X
X	if (newtop == curwind->w_top)
X		v_clear(FLine(curwind), FLine(curwind) + SIZE(curwind));
X	else
X		SetTop(curwind, newtop);
X}
X
Xv_clear(line1, line2)
Xregister int	line1;
X{
X	register struct scrimage	*phys_p, *des_p;
X
X	phys_p = &PhysScreen[line1];
X	des_p = &DesiredScreen[line1];
X
X	while (line1 <= line2) {
X		i_set(line1++, 0);
X		cl_eol();
X		phys_p->s_id = des_p->s_id = 0;
X		phys_p++, des_p++;
X	}
X}
X
XClAndRedraw()
X{
X	cl_scr(1);
X}
X
XNextPage()
X{
X	Line	*newline;
X
X	if (Asking)
X		return;
X	if (exp < 0) {
X		exp = -exp;
X		PrevPage();
X		return;
X	}
X	if (exp_p == YES)
X		UpScroll();
X	else {
X		if (in_window(curwind, curwind->w_bufp->b_last) != -1) {
X			rbell();
X			return;
X		}
X		newline = next_line(curwind->w_top, max(1, SIZE(curwind) - 1));
X		SetTop(curwind, curwind->w_line = newline);
X		if (curwind->w_bufp == curbuf)
X			SetLine(newline);
X	}
X}
X
XPrevPage()
X{
X	Line	*newline;
X
X	if (Asking)
X		return;
X	if (exp < 0) {
X		exp = -exp;
X		NextPage();
X		return;
X	}
X	if (exp_p == YES)
X		DownScroll();
X	else {
X		newline = prev_line(curwind->w_top, max(1, SIZE(curwind) - 1));
X		SetTop(curwind, curwind->w_line = newline);
X		if (curwind->w_bufp == curbuf)
X			SetLine(newline);
X	}
X}
X
XUpScroll()
X{
X	SetTop(curwind, next_line(curwind->w_top, exp));
X	if ((curwind->w_bufp == curbuf) &&
X	    (in_window(curwind, curline) == -1))
X		SetLine(curwind->w_top);
X}
X
XDownScroll()
X{
X	SetTop(curwind, prev_line(curwind->w_top, exp));
X	if ((curwind->w_bufp == curbuf) &&
X	    (in_window(curwind, curline) == -1))
X		SetLine(curwind->w_top);
X}
X
Xint	VisBell = 0,
X	RingBell = 0;	/* So if we have a lot of errors ...
X			   ring the bell only ONCE */
Xrbell()
X{
X	RingBell++;
X}
X
X/* Message prints the null terminated string onto the bottom line of the
X   terminal. */
X
Xmessage(str)
Xchar	*str;
X{
X	if (InJoverc)
X		return;
X	UpdMesg++;
X	errormsg = 0;
X	if (str != mesgbuf)
X		null_ncpy(mesgbuf, str, (sizeof mesgbuf) - 1);
X}
X
X/* End of Window */
X
XEow()
X{
X	if (Asking)
X		return;
X	SetLine(next_line(curwind->w_top, SIZE(curwind) - 1 -
X			min(SIZE(curwind) - 1, exp - 1)));
X	if (exp_p == NO)
X		Eol();
X}
X
X/* Beginning of Window */
X
XBow()
X{
X	if (Asking)
X		return;
X	SetLine(next_line(curwind->w_top, min(SIZE(curwind) - 1, exp - 1)));
X}
X
Xprivate int	LineNo,
X		last_col,
X		DoAutoNL;
Xprivate Window	*old_wind;	/* save the window we were in BEFORE
X				   before we were called, if UseBuffers
X				   is nonzero */
X
Xint	UseBuffers = FALSE;
Xint	TOabort = 0;
X
X/* This initializes the typeout.  If send-typeout-to-buffers is set
X   the buffer NAME is created (emptied if it already exists) and output
X   goes to the buffer.  Otherwise output is drawn on the screen and
X   erased by TOstop() */
X
XTOstart(name, auto_newline)
Xchar	*name;
X{
X	if (UseBuffers) {
X		old_wind = curwind;
X		pop_wind(name, YES, B_SCRATCH);
X	}
X	TOabort = LineNo = last_col = 0;
X	DoAutoNL = auto_newline;
X}
X
X/* VARARGS1 */
X
XTypeout(fmt, va_alist)
Xchar	*fmt;
Xva_dcl
X{
X	if (TOabort)
X		return;
X
X	if (!UseBuffers && (LineNo == ILI - 1)) {
X		register int	c;
X
X		LineNo = 0;
X		last_col = 0;
X		f_mess("--more--");
X		if ((c = getchar()) != ' ') {
X			TOabort++;
X			if (c != CTL(G) && c != RUBOUT)
X				Ungetc(c);
X			return;
X		}
X		f_mess(NullStr);
X	}
X
X	if (fmt) {
X		extern int	i_col;
X		char	string[132];
X		va_list	ap;
X
X		va_start(ap);
X		format(string, sizeof string, fmt, ap);
X		va_end(ap);
X		if (UseBuffers)
X			ins_str(string, NO);
X		else {
X			i_set(LineNo, last_col);
X			(void) swrite(string, NIL, YES);
X			last_col = i_col;
X		}
X	}
X	if (!UseBuffers) {
X		PhysScreen[LineNo].s_id = -1;
X		if (fmt == 0 || DoAutoNL != 0) {
X			cl_eol();
X			flusho();
X			LineNo++;
X			last_col = 0;
X		}
X	} else if (fmt == 0 || DoAutoNL != 0)
X		ins_str("\n", NO);
X}
X
XTOstop()
X{
X	int	c;
X
X	if (UseBuffers) {
X		ToFirst();
X		SetWind(old_wind);
X	} else {
X		if (TOabort)
X			return;
X		if (last_col != 0)
X			Typeout((char *) 0);
X		Typeout("----------");
X		cl_eol();
X		flusho();
X		c = getchar();
X		if (c != ' ')
X			Ungetc(c);
X	}
X}
@//E*O*F disp.c//
if test 24166 -ne "`wc -c <'disp.c'`"; then
    echo shar: error transmitting "'disp.c'" '(should have been 24166 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'fmt.c'" '(4845 characters)'
if test -f 'fmt.c' ; then 
  echo shar: will not over-write existing file "'fmt.c'"
else
sed 's/^X//' >fmt.c <<'@//E*O*F fmt.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
X * provided to you without charge, and with no warranty.  You may give  *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files.                                           *
X ************************************************************************/
X
X#include "jove.h"
X#include "io.h"
X#include "termcap.h"
X
X#include <varargs.h>
X
Xchar	mesgbuf[MESG_SIZE];
X
X/* VARARGS2 */
X
Xformat(buf, len, fmt, ap)
Xchar	*buf,
X	*fmt;
Xva_list	ap;
X{
X	File	strbuf,
X		*sp = &strbuf;
X
X 	sp->f_ptr = sp->f_base = buf;
X	sp->f_fd = -1;		/* Not legit for files */
X	sp->f_cnt = len;
X	sp->f_flags = F_STRING;
X	sp->f_bufsize = len;
X
X	doformat(sp, fmt, ap);
X	putc('\0', sp);
X}
X
Xstatic char	padc = ' ';
Xstatic File	*curiop = 0;
X
Xstatic
XPPchar(c, str)
Xint	c;
Xchar	*str;
X{
X	char	*cp = str;
X
X	if (c == '\033')
X		strcpy(cp, "ESC");
X	else if (c < ' ')
X		sprintf(cp, "C-%c", c + '@');
X	else if (c == '\177')
X		strcpy(cp, "^?");
X	else
X		sprintf(cp, "%c", c);
X}
X
Xstatic
Xputld(leftadj, width, d, base)
Xlong	d;
X{
X	int	length = 1;
X	long	tmpd = d;
X
X	while (tmpd = (tmpd / base))
X		length++;
X	if (d < 0)
X		length++;
X	if (!leftadj)
X		pad(padc, width - length);
X	if (d < 0) {
X		putc('-', curiop);
X		d = -d;
X	}
X	outld(d, base);
X	if (leftadj)
X		pad(padc, width - length);
X}
X
Xstatic
Xoutld(d, base)
Xlong	d;
X{
X	long	n;
X
X	if (n = (d / base))
X		outld(n, base);
X	putc((int) ('0' + (int) (d % base)), curiop);
X}
X
Xstatic
Xputs(leftadj, width, str)
Xchar	*str;
X{
X	int	length;
X	register char	*cp,
X			c;
X
X	if (str == 0)
X#if pyr
X		str = "";
X#else
X		str = "(null)";
X#endif
X	length = strlen(str);
X	cp = str;
X	if (!leftadj)
X		pad(' ', width - length);
X	while (c = *cp++)
X		putc(c, curiop);
X	if (leftadj)
X		pad(' ', width - length);
X}
X
Xstatic
Xpad(c, amount)
Xregister int	c,
X		amount;
X{
X	while (--amount >= 0)
X		putc(c, curiop);
X}
X
Xstatic
Xdoformat(sp, fmt, ap)
Xregister File	*sp;
Xregister char	*fmt;
Xva_list	ap;
X{
X	register char	c;
X	int	leftadj,
X		width;
X	File	*pushiop = curiop;
X
X	curiop = sp;
X
X	while (c = *fmt++) {
X		if (c != '%') {
X			putc(c, sp);
X			continue;
X		}
X
X		padc = ' ';
X		leftadj = width = 0;
X		c = *fmt++;
X		if (c == '-') {
X			leftadj++;
X			c = *fmt++;
X		}
X		if (c == '0') {
X			padc = '0';
X			c = *fmt++;
X		}
X		while (c >= '0' && c <= '9') {
X			width = width * 10 + (c - '0');
X			c = *fmt++;
X		}
X		if (c == '*') {
X			width = va_arg(ap, int);
X			c = *fmt++;
X		}
X	reswitch:
X		/* At this point, fmt points at one past the format letter. */
X		switch (c) {
X		case '%':
X			putc('%', curiop);
X			break;
X	
X		case 'D':
X			putld(leftadj, width, va_arg(ap, long), 10);
X			break;
X	
X		case 'b':
X		    {
X			Buffer	*b = va_arg(ap, Buffer *);
X
X			puts(leftadj, width, b->b_name);
X			break;
X		    }
X
X		case 'c':
X			putc(va_arg(ap, int), curiop);
X			break;
X	
X		case 'd':
X			putld(leftadj, width, (long) va_arg(ap, int), 10);
X			break;
X	
X		case 'f':	/* current command name gets inserted here! */
X			puts(leftadj, width, LastCmd->Name);
X			break;
X
X		case 'l':
X			c = Upper(*++fmt);
X			goto reswitch;
X	
X		case 'n':
X			if (va_arg(ap, int) != 1)
X				puts(leftadj, width, "s");
X			break;
X
X		case 'o':
X			putld(leftadj, width, (long) va_arg(ap, int), 8);
X			break;
X	
X		case 'p':
X		    {
X		    	char	cbuf[20];
X
X		    	PPchar(va_arg(ap, int), cbuf);
X		    	puts(leftadj, width, cbuf);
X		    	break;
X		    }
X
X		case 's':
X			puts(leftadj, width, va_arg(ap, char *));
X			break;
X		
X		default:
X			complain("Unknown format directive: \"%%%c\"", c);
X		}
X	}
X	curiop = pushiop;
X}
X
X/* VARARGS1 */
X
Xchar *
Xsprint(fmt, va_alist)
Xchar	*fmt;
Xva_dcl
X{
X	va_list	ap;
X	static char	line[100];
X
X	va_start(ap);
X	format(line, sizeof line, fmt, ap);
X	va_end(ap);
X	return line;
X}
X
X/* VARARGS1 */
X
Xprintf(fmt, va_alist)
Xchar	*fmt;
Xva_dcl
X{
X	va_list	ap;
X
X	va_start(ap);
X	doformat(stdout, fmt, ap);
X	va_end(ap);
X}
X
X/* VARARGS1 */
X
Xfprintf(fp, fmt, va_alist)
XFile	*fp;
Xchar	*fmt;
Xva_dcl
X{
X	va_list	ap;
X
X	va_start(ap);
X	doformat(fp, fmt, ap);
X	va_end(ap);
X}
X
X/* VARARGS2 */
X
Xsprintf(str, fmt, va_alist)
Xchar	*str,
X	*fmt;
Xva_dcl
X{
X	va_list	ap;
X
X	va_start(ap);
X	format(str, 130, fmt, ap);
X	va_end(ap);
X}
X
X/* VARARGS1 */
X
Xs_mess(fmt, va_alist)
Xchar	*fmt;
Xva_dcl
X{
X	va_list	ap;
X
X	if (InJoverc)
X		return;
X	va_start(ap);
X	format(mesgbuf, sizeof mesgbuf, fmt, ap);
X	va_end(ap);
X	message(mesgbuf);
X}
X
X/* VARARGS1 */
X
Xf_mess(fmt, va_alist)
Xchar	*fmt;
Xva_dcl
X{
X	va_list	ap;
X
X	va_start(ap);
X	format(mesgbuf, sizeof mesgbuf, fmt, ap);
X	va_end(ap);
X	DrawMesg(NO);
X	UpdMesg++;	/* Still needs updating (for convenience) */
X}
X
X/* VARARGS1 */
X
Xadd_mess(fmt, va_alist)
Xchar	*fmt;
Xva_dcl
X{
X	int	mesg_len = strlen(mesgbuf);
X	va_list	ap;
X
X	if (InJoverc)
X		return;
X	va_start(ap);
X	format(&mesgbuf[mesg_len], (sizeof mesgbuf) - mesg_len, fmt, ap);
X	va_end(ap);
X	message(mesgbuf);
X}
@//E*O*F fmt.c//
if test 4845 -ne "`wc -c <'fmt.c'`"; then
    echo shar: error transmitting "'fmt.c'" '(should have been 4845 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'re.h'" '(856 characters)'
if test -f 're.h' ; then 
  echo shar: will not over-write existing file "'re.h'"
else
sed 's/^X//' >re.h <<'@//E*O*F re.h//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
X * provided to you without charge, and with no warranty.  You may give  *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files.                                           *
X ************************************************************************/
X
X#define NALTS	10	/* number of alternate search strings */
X
Xextern char	searchstr[128],
X		compbuf[128],		/* global default compbuf */
X		rep_search[128],	/* replace search string */
X		rep_str[128],		/* contains replacement string */
X		*cur_compb,		/* usually points at compbuf */
X		REbuf[LBSIZE],		/* points at line we're scanning */
X		*alternates[NALTS];
X
Xextern int	REdirection,
X		REeom,
X		REbom,
X		REalt_num;
@//E*O*F re.h//
if test 856 -ne "`wc -c <'re.h'`"; then
    echo shar: error transmitting "'re.h'" '(should have been 856 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'rec.h'" '(699 characters)'
if test -f 'rec.h' ; then 
  echo shar: will not over-write existing file "'rec.h'"
else
sed 's/^X//' >rec.h <<'@//E*O*F rec.h//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
X * provided to you without charge, and with no warranty.  You may give  *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files.                                           *
X ************************************************************************/
X
Xstruct rec_head {
X	int	Uid,		/* Uid of owner. */
X		Pid;		/* Pid of jove process. */
X	time_t	UpdTime;	/* Last time this was updated. */
X	int	Nbuffers;	/* Number of buffers. */
X};
X
Xstruct rec_entry {
X	char	r_bname[128],
X		r_fname[128];
X	int	r_nlines;
X};
X
@//E*O*F rec.h//
if test 699 -ne "`wc -c <'rec.h'`"; then
    echo shar: error transmitting "'rec.h'" '(should have been 699 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'doc/cmds.doc.nr'" '(238 characters)'
if test -f 'doc/cmds.doc.nr' ; then 
  echo shar: will not over-write existing file "'doc/cmds.doc.nr'"
else
sed 's/^X//' >doc/cmds.doc.nr <<'@//E*O*F doc/cmds.doc.nr//'
X.de bp
X..
X.de NH
X..
X.de IQ
X"\\$1"
X..
X.de dc
X.sp 1
X:entry "\\$1"
X.if '\\$2'(variable)' "Variable"
X.if !'\\$2'(variable)' "Command"
X.br
X..
X.de ID
X.sp 1
X.in +5
X..
X.de DE
X.fi
X.sp 1
X.in -5
X..
X.de DS
X.nf
X.sp 1
X.in +5
X..
X.de UX
XUNIX\c
X..
X.ll 7i
@//E*O*F doc/cmds.doc.nr//
if test 238 -ne "`wc -c <'doc/cmds.doc.nr'`"; then
    echo shar: error transmitting "'doc/cmds.doc.nr'" '(should have been 238 characters)'
fi
fi # end of overwriting check
echo shar: "End of archive 2 (of 13)."
cp /dev/null ark2isdone
DONE=true
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13; do
    if test -f ark${I}isdone; then
        echo "You have run archive ${I}."
    else
        echo "You still need to run archive ${I}."
        DONE=false
    fi
done
case $DONE in
    true)
        echo "You have run all 13 archives."
        echo 'Now read the README and Makefile.'
        ;;
esac
##  End of shell archive.
exit 0



More information about the Mod.sources mailing list