2.9BSD/usr/contrib/jove/jove_c.c

/*
   Jonathan Payne at Lincoln-Sudbury Regional High School 5-25-83

   jove_c.c

   contains commands for C mode, paren matching routines are in here. */

#include "jove.h"

BUFLOC *
m_paren(orig, stop)
char	orig;		/* One we are on */
LINE	*stop;
{
	char	*origs = "(){}",
		*matches = ")(}{",
		matcher;
	int	which,
		forward,
		count = 0;
	register LINE	*lp = curline;
	register char	*cp,
			c;
	int	c_char = curchar;
	static BUFLOC	ret;

	which = index(origs, orig) - origs;
	forward = (which % 2) == 0;
	matcher = matches[which];

	while (count >= 0) {
		if ((forward && lp == stop->l_next) ||
					(!forward && lp == stop->l_prev))
			return 0;
		if (forward) {
			cp = getright(lp, genbuf) + c_char;
			while (c = *++cp) {
				c_char++;
				if (c == matcher)
					count -= NotInQuotes(genbuf, c_char);
				else if (c == orig)
					count += NotInQuotes(genbuf, c_char);
				if (count < 0)
					goto done;
			}
			lp = lp->l_next;
			c_char = -1;
		} else {
			cp = getright(lp, genbuf);
			cp += (c_char >= 0 ? c_char : (c_char = strlen(genbuf)));
			while ((cp > genbuf) && (c = *--cp)) {
				--c_char;
				if (c == matcher)
					count -= NotInQuotes(genbuf, c_char);
				else if (c == orig)
					count += NotInQuotes(genbuf, c_char);
				if (count < 0)
					goto done;
			}
			c_char = -1;
			lp = lp->l_prev;
		}
	}
done:
	if (count >= 0)
		return 0;
	ret.p_line = lp;
	ret.p_char = forward ? (cp - genbuf) + 1 : (cp - genbuf);
	return &ret;
}

Fparen()
{
	FindMatch(1);
}

Bparen()
{
	FindMatch(-1);
}

/* Move to the matching brace or paren depending on the current position
 * in the buffer.
 */

FindMatch(dir)
{
	BUFLOC	*bp;
	char	c;

	bp = dosearch(dir > 0 ? "[{(]" : "[})]", dir, 1);
	if (bp == 0)
		complain((char *) 0);
	SetDot(bp);
	if (dir > 0)
		BackChar();
	c = linebuf[curchar];
	if (c == '\0' || index("){}(", c) == 0)
		complain((char *) 0);
	if (!NotInQuotes(linebuf, curchar))	/* If in quotes */
		complain("In quotes");
	else {
		bp = m_paren(c, dir > 0 ? curbuf->b_dol : curbuf->b_zero);
		if (bp)
			SetDot(bp);
		else
			complain("No match");
	}
}

/* Make sure character at c_char is not surrounded by double
 * or single quotes.
 */

char	quots[10];

NotInQuotes(buf, pos)
char	*buf;
{
	char	quotchar = 0,
		c;
	int	i;

	if (quots[0] == 0)
		return 1;	/* Not in quotes */
	for (i = 0; i < pos && buf[i]; i++) {
		if ((c = buf[i]) == '\\') {
			i++;
			continue;
		}
		if (!index(quots, c))
			continue;
		if (quotchar == 0)
			quotchar = c;
		else if (c == quotchar)
			quotchar = 0;	/* Terminated string */
	}
	return (quotchar == 0);
}