⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE * * is provided to you without charge, and with no warranty.  You may give  * * away copies of JOVE, including sources, provided that this notice is    * * included in all the files.                                              * ***************************************************************************//* Contains commands for C mode.  Paren matching routines are in here. */#include "jove.h"#include "re.h"#include "ctype.h"#include "disp.h"private void#ifdef	CMT_FMT	FillComment proto((char *format)),#endif	FindMatch proto((int));private intbackslashed(lp, cpos)register char	*lp;register int	cpos;{	register int	cnt = 0;	while (cpos > 0 && lp[--cpos] == '\\')		cnt += 1;	return (cnt % 2);}private char	*p_types = "(){}[]";private int	mp_kind;#define MP_OKAY		0#define MP_MISMATCH	1#define MP_UNBALANCED	2#define MP_INCOMMENT	3voidmp_error(){	switch (mp_kind) {	case MP_MISMATCH:		message("[Mismatched parentheses]");		break;	case MP_UNBALANCED:		message("[Unbalanced parenthesis]");		break;	case MP_INCOMMENT:		message("[Inside a comment]");		break;	case MP_OKAY:	default:		return;	}	rbell();}/* Search from the current position for the paren that matches p_type.   Search in the direction dir.  If can_mismatch is YES then it is okay   to have mismatched parens.  If stop_early is YES then when an open   paren is found at the beginning of a line, it is assumed that there   is no point in backing up further.  This is so when you hit tab or   LineFeed outside, in-between procedure/function definitions, it won't   sit there searching all the way to the beginning of the file for a   match that doesn't exist.  {forward,backward}-s-expression are the   only ones that insist on getting the "true" story. */Bufpos *m_paren(p_type, dir, can_mismatch, can_stop)int	p_type;register int	dir;int	can_mismatch;int	can_stop;{	static Bufpos	ret;	Bufpos	savedot,		*sp;	struct RE_block	re_blk;	int	count = 0;	register char	*lp,			c;	char	p_match,		re_str[128],		*cp,		quote_c = 0;	register int	c_char;	int	in_comment = -1,		stopped = NO;	swritef(re_str, sizeof(re_str), "[(){}[\\]%s]",		(MajorMode(CMODE)) ? "/\"'" : "\"");	REcompile(re_str, YES, &re_blk);	if ((cp = strchr(p_types, p_type)) == NULL)		complain("[Cannot match %c's]", p_type);	p_match = cp[dir];	DOTsave(&savedot);	/* To make things a little faster I avoid copying lines into	   linebuf by setting curline and curchar by hand.  Warning:	   this is slightly to very risky.  When I did this there were	   lots of problems with procedures that expect the contents of	   curline to be in linebuf. */	do {		sp = docompiled(dir, &re_blk);		if (sp == NULL)			break;		lp = lbptr(sp->p_line);		curline = sp->p_line;		curchar = sp->p_char;	/* here's where I cheat */		c_char = curchar;		if (dir == FORWARD)			c_char -= 1;		if (backslashed(lp, c_char))			continue;		c = lp[c_char];		/* check if this is a comment (if we're not inside quotes) */		if (quote_c == 0 && c == '/') {			int	new_ic = in_comment;			/* close comment */			if ((c_char != 0) && lp[c_char - 1] == '*') {				new_ic = (dir == FORWARD) ? NO : YES;				if (new_ic == NO && in_comment == -1) {					count = 0;					quote_c = 0;				}			} else if (lp[c_char + 1] == '*') {				new_ic = (dir == FORWARD) ? YES : NO;				if (new_ic == NO && in_comment == -1) {					count = 0;					quote_c = 0;				}			}			in_comment = new_ic;		}		if (in_comment == YES)			continue;		if (c == '"' || c == '\'') {			if (quote_c == c)				quote_c = 0;			else if (quote_c == 0)				quote_c = c;		}		if (quote_c != 0)			continue;		if (jisopenp(c)) {			count += dir;			if (c_char == 0 && can_stop == YES && count >= 0) {				stopped = YES;				break;			}		} else if (jisclosep(c))			count -= dir;	} while (count >= 0);	ret.p_line = curline;	ret.p_char = curchar;	curline = savedot.p_line;	curchar = savedot.p_char;	/* here's where I undo it */	if (count >= 0)		mp_kind = MP_UNBALANCED;	else if (c != p_match)		mp_kind = MP_MISMATCH;	else		mp_kind = MP_OKAY;	/* If we stopped (which means we were allowed to stop) and there	   was an error, we clear the error so no error message is printed.	   An error should be printed ONLY when we are sure about the fact,	   namely we didn't stop prematurely HOPING that it was the right	   answer. */	if (stopped && mp_kind != MP_OKAY) {		mp_kind = MP_OKAY;		return NULL;	}	if (mp_kind == MP_OKAY || (mp_kind == MP_MISMATCH && can_mismatch == YES))		return &ret;	return NULL;}private voiddo_expr(dir, skip_words)register int	dir;int	skip_words;{	register char	c,			syntax = (dir == FORWARD) ? C_BRA : C_KET;	if (dir == BACKWARD)		b_char(1);	c = linebuf[curchar];	for (;;) {		if (!skip_words && ismword(c)) {		    WITH_TABLE(curbuf->b_major)			if (dir == FORWARD)			    f_word(1);			else			    b_word(1);		    END_TABLE();		    break;		} else if (has_syntax(c, syntax)) {			FindMatch(dir);			break;		}		f_char(dir);		if (eobp() || bobp())			return;		c = linebuf[curchar];	}}voidFSexpr(){	register int	num = arg_value();	if (num < 0) {		set_arg_value(-num);		BSexpr();	}	while (--num >= 0)		do_expr(FORWARD, NO);}voidFList(){	register int	num = arg_value();	if (num < 0) {		set_arg_value(-num);		BList();	}	while (--num >= 0)		do_expr(FORWARD, YES);}voidBSexpr(){	register int	num = arg_value();	if (num < 0) {		negate_arg_value();		FSexpr();	}	while (--num >= 0)		do_expr(BACKWARD, NO);}voidBList(){	register int	num = arg_value();	if (num < 0) {		negate_arg_value();		FList();	}	while (--num >= 0)		do_expr(BACKWARD, YES);}voidBUpList(){	Bufpos	*mp;	char	c = (MajorMode(CMODE) ? '}' : ')');	mp = m_paren(c, BACKWARD, NO, YES);	if (mp == NULL)		mp_error();	else		SetDot(mp);}voidFDownList(){	Bufpos	*sp;	char	*sstr = MajorMode(CMODE) ? "[{([\\])}]" : "[()]";	sp = dosearch(sstr, FORWARD, YES);	if (sp == NULL || has_syntax(lcontents(sp->p_line)[sp->p_char - 1], C_KET))		complain("[No contained expression]");	SetDot(sp);}/* Move to the matching brace or paren depending on the current position   in the buffer. */private voidFindMatch(dir)int	dir;{	register Bufpos	*bp;	register char	c = linebuf[curchar];	if ((strchr(p_types, c) == NULL) ||	    (backslashed(linebuf, curchar)))		complain((char *)NULL);	if (dir == FORWARD)		f_char(1);	bp = m_paren(c, dir, YES, NO);	if (dir == FORWARD)		b_char(1);	if (bp != NULL)		SetDot(bp);	mp_error();	/* if there is an error the user wants to			   know about it */}#define ALIGN_ARGS	(-1)/* If CArgIndent == ALIGN_ARGS then the indentation routine will   indent a continued line by lining it up with the first argument.   Otherwise, it will indent CArgIndent characters past the indent   of the first line of the procedure call. */int	CArgIndent = ALIGN_ARGS;/* indent for C code */Bufpos *c_indent(brace)int	brace;{	Bufpos	*bp;	int	new_indent = 0,		current_indent,		increment;	if (brace == NO)		increment = CIndIncrmt;	else		increment = 0;	/* Find matching paren, which may be a mismatch now.  If it	   is not a matching curly brace then it is a paren (most likely).	   In that case we try to line up the arguments to a procedure	   or inside an of statement. */	if ((bp = m_paren('}', BACKWARD, YES, YES)) != NULL) {		Bufpos	save;		int	matching_indent;		DOTsave(&save);		SetDot(bp);		/* go to matching paren */		ToIndent();		matching_indent = calc_pos(linebuf, curchar);		SetDot(bp);		switch (linebuf[curchar]) {		case '{':			new_indent = matching_indent;			if (!bolp()) {				b_char(1);				/* If we're not within the indent then we				   can assume that there is either a C keyword				   line DO on the line before the brace, or				   there is a parenthesized expression.  If				   that's the case we want to go backward				   over that to the beginning of the expression				   so that we can get the correct indent for				   this matching brace.  This handles wrapped				   if statements, etc. */				if (!within_indent()) {					Bufpos	savematch;					savematch = *bp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -