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

📄 buf.c

📁 早期freebsd实现
💻 C
字号:
/*************************************************************************** * 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 that deal with creating, selecting, killing and   listing buffers, and buffer modes, and find-file, etc. */#include "jove.h"#include "ctype.h"#include "disp.h"#ifdef	IPROCS# include "fp.h"# include "iproc.h"#endif#ifdef	MAC# include "mac.h"#else# include <sys/stat.h>#endifprivate void	setbname proto((Buffer *, char *));private char	*Mainbuf = "Main",	*NoName = "Sans un nom!";Buffer	*world = NULL,		/* First in the list */	*curbuf = NULL,		/* pointer into world for current buffer */	*lastbuf = NULL;	/* Last buffer we were in so we have a default				   buffer during a select buffer. *//* Toggle BIT in the current buffer's minor mode flags.  If argument is   supplied, a positive one always turns on the mode and zero argument   always turns it off. */voidTogMinor(bit)int	bit;{	if (is_an_arg()) {		if (arg_value() == 0)			curbuf->b_minor &= ~bit;		else			curbuf->b_minor |= bit;	} else		curbuf->b_minor ^= bit;	UpdModLine = YES;}/* Creates a new buffer, links it at the end of the buffer chain, and   returns it. */private Buffer	*free_bufs = NULL;private Buffer *buf_alloc(){	register Buffer	*b,			*lastbp;	lastbp = NULL;	for (b = world; b != NULL; b = b->b_next)		lastbp = b;	if (free_bufs != NULL) {		b = free_bufs;		free_bufs = b->b_next;	} else {		b = (Buffer *) emalloc(sizeof (Buffer));	}	if (lastbp)		lastbp->b_next = b;	else		world = b;	b->b_first = NULL;	b->b_next = NULL;#ifdef	MAC	b->Type = BUFFER;	/* kludge, but simplifies menu handlers */	b->Name = NULL;#endif	return b;}/* Makes a buffer and initializes it.  Obsolete.  Used to take two   arguments, a buffer name and a file name. */private Buffer *mak_buf(){	register Buffer	*newb;	register int	i;	newb = buf_alloc();	newb->b_fname = NULL;	newb->b_name = NoName;	set_ino(newb);	newb->b_marks = NULL;	newb->b_themark = 0;		/* Index into markring */	/* No marks yet */	for (i = 0; i < NMARKS; i++)		newb->b_markring[i] = NULL;	newb->b_modified = NO;	newb->b_type = B_FILE;  /* File until proven SCRATCH */	newb->b_ntbf = NO;	newb->b_minor = 0;	newb->b_major = TEXT;	newb->b_first = NULL;	newb->b_map = NULL;#ifdef	IPROCS	newb->b_process = NULL;#endif	initlist(newb);#ifdef	MAC	Bufchange = YES;#endif	return newb;}voidReNamBuf(){	register char	*new = NULL,			*prompt = ProcFmt,			*second = "%s already exists; new name? ";	for (;;) {		new = ask((char *)NULL, prompt, new);		if (!buf_exists(new))			break;		prompt = second;	}	setbname(curbuf, new);}voidFindFile(){	register char	*name;	char	fnamebuf[FILESIZE];	name = ask_file((char *)NULL, curbuf->b_fname, fnamebuf);	SetABuf(curbuf);	SetBuf(do_find(curwind, name, NO));}private voidmkbuflist(bnamp, ebnamp)register char	**bnamp;char		**ebnamp;{	register Buffer	*b;	for (b = world; b != NULL; b = b->b_next) {		if (b->b_name != NULL) {			*bnamp++ = b->b_name;			if (bnamp >= ebnamp)				complain("too many buffers to list");		}	}	*bnamp = NULL;}char *ask_buf(def)Buffer	*def;{	char	*bnames[100];	register char	*bname;	register int	offset;	char	prompt[100];	if (def != NULL && def->b_name != NULL) {		swritef(prompt, sizeof(prompt), ": %f (default %s) ",			def->b_name);	} else {		swritef(prompt, sizeof(prompt), ProcFmt);	}	mkbuflist(bnames, &bnames[sizeof(bnames) / sizeof(*bnames)]);	offset = complete(bnames, prompt, RET_STATE);	if (offset == EOF)		complain((char *)NULL);	if (offset == ORIGINAL || offset == AMBIGUOUS) {		bname = Minibuf;	} else if (offset == NULLSTRING) {		if (def == NULL)			complain((char *)NULL);		bname = def->b_name;	} else {		if (offset < 0)			complain((char *)NULL);		bname = bnames[offset];	}	return bname;}voidBufSelect(){	register char	*bname;	bname = ask_buf(lastbuf);	SetABuf(curbuf);	SetBuf(do_select(curwind, bname));}#ifdef	MSDOSprivate voidBufNSelect(n)int	n;{	register Buffer	*b;	for (b = world; b != NULL; b = b->b_next) {		if (b->b_name != NULL) {			if (n == 0) {				SetABuf(curbuf);				SetBuf(do_select(curwind, b->b_name));				return;			}			n -= 1;		}	}	complain("[No such buffer]");}void Buf0Select() { BufNSelect(0); }void Buf1Select() { BufNSelect(1); }void Buf2Select() { BufNSelect(2); }void Buf3Select() { BufNSelect(3); }void Buf4Select() { BufNSelect(4); }void Buf5Select() { BufNSelect(5); }void Buf6Select() { BufNSelect(6); }void Buf7Select() { BufNSelect(7); }void Buf8Select() { BufNSelect(8); }void Buf9Select() { BufNSelect(9); }#endif	/* MSDOS */private voiddefb_wind(b)register Buffer *b;{	register Window	*w = fwind;	char	*alt;	if (lastbuf == b || lastbuf == NULL) {		lastbuf = NULL;		alt = (b->b_next != NULL) ? b->b_next->b_name : Mainbuf;	} else		alt = lastbuf->b_name;	do {		if (w->w_bufp == b) {			if (one_windp() || alt != Mainbuf)				(void) do_select(w, alt);			else {				Window	*save = w->w_next;				del_wind(w);				w = save->w_prev;			}		}		w = w->w_next;	} while (w != fwind || w->w_bufp == b);}private Buffer *getNMbuf(){	register Buffer	*delbuf;	register char	*bname;	bname = ask_buf(curbuf);	if ((delbuf = buf_exists(bname)) == NULL)		complain("[No such buffer]");	if (delbuf->b_modified)		confirm("%s modified, are you sure? ", bname);	return delbuf;}voidBufErase(){	register Buffer	*delbuf;	if ((delbuf = getNMbuf()) != NULL) {		initlist(delbuf);		delbuf->b_modified = NO;	}}/* Free a buffer structure. * The actual struct is preserved to reduce the damage * from dangling references to it.  They seem to be pervasive. * We try to reset enough that a dangling reference will be useless. */private voidkill_buf(delbuf)register Buffer	*delbuf;{	register Buffer	*b,			*lastb = NULL;#ifdef	IPROCS	pbuftiedp(delbuf);	/* check for lingering processes */#endif	/* clean up windows associated with this buffer */	if (delbuf == curbuf)		curbuf = NULL;	if (delbuf == lastbuf)		lastbuf = curbuf;	/* even if NULL */	defb_wind(delbuf);	if (curbuf == NULL)		SetBuf(curwind->w_bufp);	/* unlink the buffer */	for (b = world; b != NULL; lastb = b, b = b->b_next)		if (b == delbuf)			break;	if (lastb)		lastb->b_next = delbuf->b_next;	else		world = delbuf->b_next;#ifndef	MAC	if (perr_buf == delbuf) {		ErrFree();		perr_buf = NULL;	}#endif	lfreelist(delbuf->b_first);	delbuf->b_first = delbuf->b_dot = delbuf->b_last = NULL;	if (delbuf->b_name) {		free((UnivPtr) delbuf->b_name);		delbuf->b_name = NULL;	}	if (delbuf->b_fname) {		free((UnivPtr) delbuf->b_fname);		delbuf->b_fname = NULL;	}	flush_marks(delbuf);	delbuf->b_marks = NULL;	delbuf->b_next = free_bufs;	free_bufs = delbuf;#ifdef	MAC	Bufchange = YES;	delbuf->Name = NULL;#endif}/* offer to kill some buffers */voidKillSome(){	register Buffer	*b,			*next;	Buffer	*oldb;	register char	*y_or_n;	for (b = world; b != NULL; b = next) {		next = b->b_next;		if (yes_or_no_p("Kill %s? ", b->b_name) == NO)			continue;		if (IsModified(b)) {			y_or_n = ask("No", "%s modified; should I save it? ", b->b_name);			if (CharUpcase(*y_or_n) == 'Y') {				oldb = curbuf;				SetBuf(b);				SaveFile();				SetBuf(oldb);			}		}		kill_buf(b);	}}voidBufKill(){	Buffer	*b;	if ((b = getNMbuf()) == NULL)		return;	kill_buf(b);}private char *line_cnt(b, buf, size)register Buffer	*b;char	*buf;size_t	size;{	register int	nlines = 0;	register Line	*lp;	for (lp = b->b_first; lp != NULL; lp = lp->l_next, nlines++)		;	swritef(buf, size, "%d", nlines);	return buf;}private const char	*const TypeNames[] = {	NULL,	"Scratch",	"File",	"Process",};voidBufList(){	register char	*fmt = "%-2s %-5s %-11s %-1s %-*s  %-s";	register Buffer	*b;	int	bcount = 1,		/* To give each buffer a number */		buf_width = 11;	char	nbuf[10];	for (b = world; b != NULL; b = b->b_next)		buf_width = max(buf_width, (int)strlen(b->b_name));	TOstart("Buffer list", TRUE);	/* true means auto-newline */	Typeout("(* means buffer needs saving)");	Typeout("(+ means file hasn't been read yet)");	Typeout(NullStr);	Typeout(fmt, "NO", "Lines", "Type", NullStr, buf_width, "Name", "File");	Typeout(fmt, "--", "-----", "----", NullStr, buf_width, "----", "----");	for (b = world; b != NULL; b = b->b_next) {		Typeout(fmt, itoa(bcount++),				line_cnt(b, nbuf, sizeof(nbuf)),				TypeNames[b->b_type],				IsModified(b) ? "*" :					 b->b_ntbf ? "+" : NullStr,				buf_width,				/* For the * (variable length field) */				b->b_name,				filename(b));		if (TOabort)			break;	}	TOstop();}private voidbufname(b)register Buffer	*b;{	char	tmp[100],		*cp;	int	try = 1;	if (b->b_fname == NULL)		complain("[No file name]");	cp = basename(b->b_fname);	strcpy(tmp, cp);	while (buf_exists(tmp)) {		swritef(tmp, sizeof(tmp), "%s.%d", cp, try);		try += 1;	}	setbname(b, tmp);}voidinitlist(b)register Buffer	*b;{	lfreelist(b->b_first);	b->b_first = b->b_dot = b->b_last = NULL;	(void) listput(b, b->b_first);	SavLine(b->b_dot, NullStr);	b->b_char = 0;	AllMarkSet(b, b->b_dot, 0);	if (b == curbuf)		getDOT();}/* Returns pointer to buffer with name NAME, or if NAME is a string of digits   returns the buffer whose number equals those digits.  Otherwise, returns   NULL. */Buffer *buf_exists(name)register char	*name;{	register Buffer	*bp;	int	n;	if (name == NULL)		return NULL;	for (bp = world; bp != NULL; bp = bp->b_next)		if (strcmp(bp->b_name, name) == 0)			return bp;	/* Doesn't match any names.  Try for a buffer number... */	if (chr_to_int(name, 10, YES, &n) != INT_BAD) {		for (bp = world; n > 1; bp = bp->b_next) {			if (bp == NULL)				break;			n -= 1;		}		return bp;	}	return NULL;}/* Returns buffer pointer with a file name NAME, if one exists.  Stat's the   file and compares inodes, in case NAME is a link, as well as the actual   characters that make up the file name. */Buffer *file_exists(name)register char	*name;{	struct stat	stbuf;	register struct stat	*s = &stbuf;	register Buffer	*b = NULL;	char	fnamebuf[FILESIZE];#ifdef	MSDOS	strlwr(name);#endif	/* MSDOS */	if (name) {		PathParse(name, fnamebuf);		if (stat(fnamebuf, s) == -1)			s->st_ino = 0;		for (b = world; b != NULL; b = b->b_next) {			if (#ifndef	MSDOS			    (b->b_ino != 0 && b->b_ino == s->st_ino &&			     b->b_dev != 0 && b->b_dev == s->st_dev) ||#endif	/* MSDOS */			    (b->b_fname != NULL &&			     strcmp(b->b_fname, fnamebuf) == 0))				break;		}	}	return b;}private voidsetbname(b, name)register Buffer	*b;register char	*name;{	UpdModLine = YES;	/* Kludge ... but speeds things up considerably */	if (name != NULL) {		if (b->b_name == NoName)			b->b_name = NULL;		b->b_name = freealloc((UnivPtr) b->b_name, strlen(name) + 1);		strcpy(b->b_name, name);	} else {		b->b_name = NULL;	}#ifdef	MAC	Bufchange = YES;#endif}voidsetfname(b, name)register Buffer	*b;register char	*name;{	char	wholename[FILESIZE],		oldname[FILESIZE],		*oldptr = oldname;	Buffer	*save = curbuf;	SetBuf(b);	UpdModLine = YES;	/* Kludge ... but speeds things up considerably */	if (b->b_fname == NULL)		oldptr = NULL;	else		strcpy(oldname, b->b_fname);	if (name) {#ifdef	MSDOS		strlwr(name);#endif	/* MSDOS */		PathParse(name, wholename);		curbuf->b_fname = freealloc((UnivPtr) curbuf->b_fname, strlen(wholename) + 1);		strcpy(curbuf->b_fname, wholename);	} else		b->b_fname = NULL;	DoAutoExec(curbuf->b_fname, oldptr);	curbuf->b_mtime = curbuf->b_dev = curbuf->b_ino = 0;	/* until they're known. */	SetBuf(save);#ifdef	MAC	Bufchange = YES;#endif}voidset_ino(b)register Buffer	*b;{	struct stat	stbuf;	if (b->b_fname == NULL || stat(pr_name(b->b_fname, NO), &stbuf) == -1) {		b->b_dev = 0;		b->b_ino = 0;		b->b_mtime = 0;	} else {		b->b_dev = stbuf.st_dev;		b->b_ino = stbuf.st_ino;		b->b_mtime = stbuf.st_mtime;	}}/* Find the file `fname' into buf and put in in window `w' */Buffer *do_find(w, fname, force)register Window	*w;register char	*fname;bool	force;{	register Buffer	*b;	b = file_exists(fname);	if (b == NULL) {		b = mak_buf();		setfname(b, fname);		bufname(b);		set_ino(b);		b->b_ntbf = YES;	}	if (force) {		Buffer	*oldb = curbuf;		SetBuf(b);	/* this'll read the file */		SetBuf(oldb);	}	if (w)		tiewind(w, b);	return b;}/* set alternate buffer */voidSetABuf(b)Buffer	*b;{	if (b != NULL)		lastbuf = b;}/* check to see if BP is a valid buffer pointer */private boolvalid_bp(bp)register Buffer	*bp;{	register Buffer	*b;	for (b = world; b != NULL; b = b->b_next)		if (b == bp)			return YES;	return NO;}voidSetBuf(newbuf)register Buffer	*newbuf;{	if (newbuf == curbuf || newbuf == NULL)		return;	if (!valid_bp(newbuf))		complain("Internal error: (0x%x) is not a valid buffer pointer!", newbuf);	lsave();	curbuf = newbuf;	curline = newbuf->b_dot;	curchar = newbuf->b_char;	getDOT();	/* do the read now ... */	if (curbuf->b_ntbf)		read_file(curbuf->b_fname, NO);#ifdef	MAC	Modechange = YES;#endif}Buffer *do_select(w, name)register Window	*w;register char	*name;{	register Buffer	*new;	if ((new = buf_exists(name)) == NULL) {		new = mak_buf();		setfname(new, (char *)NULL);		setbname(new, name);	}	if (w)		tiewind(w, new);	return new;}voidbuf_init(){	SetBuf(do_select(curwind, Mainbuf));}

⌨️ 快捷键说明

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