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

📄 insert.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	char	save[LBSIZE],		buf[LBSIZE];	Line	*startline = atline;	int	startchar = atchar;	lsave();	if (whatbuf)		modify();	(void) ltobuf(atline, genbuf);	strcpy(save, &genbuf[atchar]);	(void) ltobuf(fline, buf);	if (fline == tline)		buf[tchar] = '\0';	linecopy(genbuf, atchar, &buf[fchar]);	atline->l_dline = putline(genbuf);	makedirty(atline);	fline = fline->l_next;	while (fline != tline->l_next) {		newline = listput(whatbuf, atline);		newline->l_dline = fline->l_dline;		makedirty(newline);		fline = fline->l_next;		atline = newline;		atchar = 0;	}	getline(atline->l_dline, genbuf);	atchar += tchar;	linecopy(genbuf, atchar, save);	atline->l_dline = putline(genbuf);	makedirty(atline);	IFixMarks(startline, startchar, atline, atchar);	bp.p_line = atline;	bp.p_char = atchar;	this_cmd = YANKCMD;	getDOT();			/* Whatever used to be in linebuf */	return &bp;}voidYankPop(){	Line	*line,		*last;	Mark	*mp = CurMark();	Bufpos	*dot;	int	dir = -1;	/* Direction to rotate the ring */	if (last_cmd != YANKCMD)		complain("Yank something first!");	lfreelist(reg_delete(mp->m_line, mp->m_char, curline, curchar));	/* Now must find a recently killed region. */	if (arg_value() < 0)		dir = 1;	killptr += dir;	for (;;) {		if (killptr < 0)			killptr = NUMKILLS - 1;		else if (killptr >= NUMKILLS)			killptr = 0;		if (killbuf[killptr])			break;		killptr += dir;	}	this_cmd = YANKCMD;	line = killbuf[killptr];	last = lastline(line);	dot = DoYank(line, 0, last, length(last), curline, curchar, curbuf);	MarkSet(CurMark(), curline, curchar);	SetDot(dot);}/* This is an attempt to reduce the amount of memory taken up by each line.   Without this each malloc of a line uses sizeof (line) + sizeof(HEADER)   where line is 3 words and HEADER is 1 word.   This is going to allocate memory in chucks of CHUNKSIZE * sizeof (line)   and divide each chuck into Lines.  A line is free in a chunk when its   line->l_dline == NULL_DADDR, so freeline sets l_dline to NULL_DADDR. */#define CHUNKSIZE	300struct chunk {	struct chunk	*c_nextchunk;	/* Next chunk of lines */	int	c_nlines;	/* Number of lines in this chunk (so they				   don't all have to be CHUNKSIZE long). */	Line	c_block[1 /* or larger */];	/* Chunk of memory */};private struct chunk	*fchunk = NULL;	/* first chunk */private Line	*ffline = NULL;	/* First free line */private Line	*faline = NULL;	/* First available line */private voidfreeline(line)register Line	*line;{	line->l_dline = NULL_DADDR;	line->l_next = ffline;	if (ffline)		ffline->l_prev = line;	line->l_prev = NULL;	ffline = line;}/* Make sure that there are no dangling references to lines in the free list, * then move them to the end of the avail list. */private voidRecycleLines(){	if (ffline == NULL)		return;	/* nothing to do */	ChkErrorLines();	/* ChkWindowLines(); -- nothing needs attention */	/* ChkBufLines(); -- nothing needs attention */	if (faline == NULL) {		faline = ffline;	} else {		Line	*laline = lastline(faline);		laline->l_next = ffline;		ffline->l_prev = laline;	}	ffline = NULL;}voidlfreelist(first)register Line	*first;{	if (first != NULL)		lfreereg(first, lastline(first));}/* Append region from line1 to line2 onto the free list of lines */voidlfreereg(line1, line2)register Line	*line1,		*line2;{	register Line	*next,			*last = line2->l_next;	while (line1 != last) {		next = line1->l_next;		freeline(line1);		line1 = next;	}}private boolnewchunk(){	register Line	*newline;	register int	i;	struct chunk	*f;	int	nlines = CHUNKSIZE;	bool	done_gc = NO;	for (;;) {		f = (struct chunk *) malloc(			(sizeof(struct chunk) - sizeof(Line))			+ (sizeof(Line) * nlines));		if (f != NULL)			break;		if (!done_gc) {			GCchunks();			done_gc = YES;		} else {			nlines /= 2;			if (nlines <= 0)				return NO;		}	}	f->c_nlines = nlines;	for (i = 0, newline = f->c_block; i < nlines; newline++, i++) {		newline->l_dline = NULL_DADDR;		newline->l_next = faline;		if (faline)			faline->l_prev = newline;		newline->l_prev = NULL;		faline = newline;	}	f->c_nextchunk = fchunk;	fchunk = f;	return YES;}/* New BUFfer LINE */Line *nbufline(){	register Line	*newline;	if (faline == NULL) {		RecycleLines();		if (faline == NULL) {			if (!newchunk())				complain("[Out of lines] ");		}	}	newline = faline;	faline = newline->l_next;	if (faline)		faline->l_prev = NULL;	return newline;}/* Remove the free lines, in chunk c, from the free list because they are   no longer free. */private voidremfreelines(c)register struct chunk	*c;{	register Line	*lp;	register int	i;	for (lp = c->c_block, i = c->c_nlines; i != 0 ; lp++, i--) {		if (lp->l_prev == NULL)			faline = lp->l_next;		else			lp->l_prev->l_next = lp->l_next;		if (lp->l_next != NULL)			lp->l_next->l_prev = lp->l_prev;	}}/* This is used to garbage collect the chunks of lines when malloc fails   and we are NOT looking for a new buffer line.  This goes through each   chunk, and if every line in a given chunk is not allocated, the entire   chunk is `free'd by "free()". *//* ??? I think that this WILL be called when we are looking for a new * buffer line: nbufline() => newchunk() => GCchunks() -- DHR */voidGCchunks(){	register struct chunk	*cp;	struct chunk	*prev = NULL,			*next;	register int	i;	register Line	*newline;	RecycleLines();	for (cp = fchunk; cp != NULL; cp = next) {		next = cp->c_nextchunk;		for (i = cp->c_nlines, newline = cp->c_block; ; newline++, i--) {			if (i == 0) {				/* Empty: unlink and free it!!! */				if (prev == NULL)					fchunk = cp->c_nextchunk;				else					prev->c_nextchunk = cp->c_nextchunk;				remfreelines(cp);				free((UnivPtr) cp);				break;			}			if (newline->l_dline != NULL_DADDR) {				/* it's a keeper */				prev = cp;				break;			}		}	}}#ifdef	LISP#include "re.h"/* Grind S-Expr */voidGSexpr(){	Bufpos	dot,		end;	if (linebuf[curchar] != '(')		complain((char *)NULL);	DOTsave(&dot);	FSexpr();	DOTsave(&end);	SetDot(&dot);	for (;;) {		if (curline == end.p_line)			break;		line_move(FORWARD, 1, NO);		if (!blnkp(linebuf))			(void) lisp_indent();	}	SetDot(&dot);}/* lisp_indent() indents a new line in Lisp Mode, according to where   the matching close-paren would go if we typed that (sort of). */private List	*specials = NULL;private voidinit_specials(){	static char *const words[] = {		"case",		"def",		"dolist",		"fluid-let",		"lambda",		"let",		"lexpr",		"macro",		"named-l",	/* named-let and named-lambda */		"nlambda",		"prog",		"selectq",		NULL	};	char	*const *wordp = words;	while (*wordp != NULL)		list_push(&specials, (UnivPtr) *wordp++);}voidAddSpecial(){	char	*word;	register List	*lp;	if (specials == NULL)		init_specials();	word = ask((char *)NULL, ProcFmt);	for (lp = specials; lp != NULL; lp = list_next(lp))		if (strcmp((char *) list_data(lp), word) == 0)			return;		/* already in list */	(void) list_push(&specials, (UnivPtr) copystr(word));}private Bufpos *lisp_indent(){	Bufpos	*bp,		savedot;	int	goal;	bp = m_paren(')', BACKWARD, NO, YES);	if (bp == NULL)		return NULL;	/* We want to end up		(atom atom atom ...		      ^ here.	 */	DOTsave(&savedot);	SetDot(bp);	f_char(1);	if (linebuf[curchar] != '(') {		register List	*lp;		if (specials == NULL)			init_specials();		for (lp = specials; lp != NULL; lp = list_next(lp))			if (casencmp((char *) list_data(lp),				     &linebuf[curchar],				     strlen((char *) list_data(lp))) == 0)				break;		if (lp == NULL) {	/* not special */			int	c_char = curchar;			WITH_TABLE(curbuf->b_major)				f_word(1);			END_TABLE();			if (LookingAt("[ \t]*;\\|[ \t]*$", linebuf, curchar)) {				curchar = c_char;			} else {				while (linebuf[curchar] == ' ')					curchar += 1;			}		} else {			curchar += 1;		}	}	goal = calc_pos(linebuf, curchar);	SetDot(&savedot);	Bol();	n_indent(goal);	return bp;}#endif	/* LISP */

⌨️ 快捷键说明

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