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

Compare this file to the similar file:
Show the results in this format:

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

   jove_buf.c
   
   Contains commands that deal with creating, selecting, killing and
   listing buffers.  (And find-file) */

#include "jove.h"

#include <sys/types.h>
#include <sys/stat.h>

char	*Mainbuf = "Main";

int	flen,
	blen;
BUFFER	*lastbuf = 0;	/* Last buffer we were in so we have a default
			 * buffer during a select buffer.
			 */

char *
filename(bp)
BUFFER	*bp;
{
	return bp->b_fname ? bp->b_fname : "[No file]";
}

char *
itoa(num)
{
	static char	line[10];

	return sprintf(line,"%d", num);
}

AllInts(str)
register char	*str;
{
	register char	c;

	while ((c = *str++) >= '0' && c <= '9')
		;
	return c == 0;
}

BUFFER *
buf_exists(name)
char	*name;
{
	BUFFER	*bp;
	int	n;

	if (name)
		for (bp = world; bp; bp = bp->b_next)
			if (bp->b_zero && strcmp(bp->b_name, name) == 0)
				return bp;

	/* Doesn't match any names.  Try for a buffer number */

	if (AllInts(name) && (n = atoi(name)) > 0) {
		for (bp = world; n - 1 > 0; ) {
			if (bp == 0)
				break;
			if (bp->b_zero == 0)
				continue;
			bp = bp->b_next;
			--n;
		}
		return bp;
	}

	return 0;
}

BUFFER *
file_exists(fname)
char	*fname;
{
	struct stat	stbuf;
	BUFFER	*bp;

	if (fname) {
		if (stat(fname, &stbuf) == -1)
			stbuf.st_ino = -1;
		for (bp = world; bp; bp = bp->b_next) {
			if (bp->b_zero == 0)
				continue;
			if ((bp->b_ino != -1) && (bp->b_ino == stbuf.st_ino))
				return bp;
			if (strcmp(bp->b_fname, fname) == 0)
				return bp;
		}
	}
	return 0;
}

max(a, b)
int a, b;
{
	return a > b ? a : b;
}

BUFFER *
findbuf()
{
	BUFFER	*bp,
		*lastbp;

	lastbp = 0;
	for (bp = world; bp; lastbp = bp, bp = bp->b_next)
		if (bp->b_zero == 0)
			break;
	if (bp == 0) {
		bp = (BUFFER *) emalloc(sizeof (BUFFER));
		if (lastbp)
			lastbp->b_next = bp;
		else
			world = bp;
		bp->b_zero = 0;
		bp->b_next = 0;
	}
	return bp;
}

extern int
	OverWrite(),
	TextInsert(),
	SelfInsert(),
	DoParen(),
	CTab(),
	LineAI(),
	Newline();

setfuncs(flags)
int	*flags;
{
	UpdModLine++;	/* Kludge ... but speeds things up considerably */
	copy_n(curbuf->b_flags, flags, NFLAGS);

	if (IsFlagSet(flags, OVERWRITE))
		BindInserts(OverWrite);
	else if (IsFlagSet(flags, TEXTFILL))
		BindInserts(TextInsert);
	else
		BindInserts(SelfInsert);
	if (IsFlagSet(flags, CMODE) || IsFlagSet(flags, MATCHING)) {
		BindFunc(mainmap, '}', DoParen);
		BindFunc(mainmap, ')', DoParen);
	} else {
		BindFunc(mainmap, '}', SelfInsert);
		BindFunc(mainmap, ')', SelfInsert);
	}
	if (IsFlagSet(flags, CMODE))
		BindFunc(mainmap, CTL(I), CTab);
	else
		BindFunc(mainmap, CTL(I), SelfInsert);
	if (IsFlagSet(flags, AUTOIND))
		BindFunc(mainmap, CTL(M), LineAI);
	else
		BindFunc(mainmap, CTL(M), Newline);
}

noflags(f)
register int	*f;
{
	register int	i = NFLAGS;

	while (i--)
		*f++ = 0;
}

setflags(buf)
BUFFER	*buf;
{
	copy_n(buf->b_flags, origflags, NFLAGS);
	SetUnmodified(buf);
	buf->b_type = NORMALBUF;	/* Normal until proven SCRATCHBUF */
}

BUFFER *
mak_buf(fname, bname)
char	*fname,
	*bname;
{
	register BUFFER	*freebuf;
	register int	i;

	freebuf = buf_exists(bname);
	if (!freebuf) {
		freebuf = findbuf();
		freebuf->b_fname = freebuf->b_name = 0;
		setbname(freebuf, bname);
		setfname(freebuf, fname);
		set_ino(freebuf);
		freebuf->b_marks = 0;
		freebuf->b_themark = 0;		/* Index into markring */
		for (i = 0; i < NMARKS; i++)
			freebuf->b_markring[i] = 0;
		/* No marks yet */
		setflags(freebuf);
		freebuf->b_zero = 0;
		initlist(freebuf);
	}
	return freebuf;
}

char *
ralloc(obj, size)
char	*obj;
{
	char	*new;
	if (obj)
		new = realloc(obj, (unsigned) size);
	if (new == 0 || !obj)
		new = emalloc(size);
	if (new == 0)
		error("No memory in ralloc");
	return new;
}

setbname(bp, name)
BUFFER	*bp;
char	*name;
{
	UpdModLine++;	/* Kludge ... but speeds things up considerably */
	if (name) {
		bp->b_name = ralloc(bp->b_name, strlen(name) + 1);
		strcpy(bp->b_name, name);
	} else
		bp->b_name = 0;
}

setfname(bp, name)
BUFFER	*bp;
char	*name;
{
	UpdModLine++;	/* Kludge ... but speeds things up considerably */
	if (name) {
		bp->b_fname = ralloc(bp->b_fname, strlen(name) + 1);
		strcpy(bp->b_fname, name);
	} else
		bp->b_fname = 0;
}

set_ino(bp)
BUFFER	*bp;
{
	struct stat	stbuf;

	if (bp->b_fname && stat(bp->b_fname, &stbuf) == -1)
		bp->b_ino = -1;
	else
		bp->b_ino = stbuf.st_ino;
}

/* Find the file `fname' into buf and put in in window `wp' */

BUFFER *
do_find(wp, fname)
WINDOW	*wp;
char	*fname;
{
	BUFFER	*oldb = curbuf,
		*bp;

	oldb = curbuf;
	bp = file_exists(fname);
	if (bp == 0) {
		bp = mak_buf(fname, (char *) 0);
		bufname(bp);
		SetBuf(bp);
		read_file(bp->b_fname);
		SetBuf(oldb);
	}
	if (wp)
		tiewind(wp, bp);
	return bp;
}

tiewind(wp, bp)
WINDOW	*wp;
BUFFER	*bp;
{
	wp->w_line = bp->b_dot;
	wp->w_char = bp->b_char;
	if (wp->w_bufp != bp) {
		wp->w_bufp = bp;
		CalcTop(wp);
	}
}

FindFile()
{
	char	*name;

	name = ask(curbuf->b_fname, FuncName());
	lastbuf = curbuf;
	SetBuf(do_find(curwind, name));
}

SetBuf(newbuf)
BUFFER	*newbuf;
{
	if (newbuf == curbuf)
		return;
	lastbuf = curbuf;
	copy_n(curbuf->b_flags, globflags, NFLAGS);
	lsave();
	curbuf = newbuf;
	getDOT();
	copy_n(globflags, curbuf->b_flags, NFLAGS);
	setfuncs(curbuf->b_flags);
}	

SelBuf()
{
	char	*bname;

	bname = ask(lastbuf ? lastbuf->b_name : 0, FuncName());
	lastbuf = curbuf;
	SetBuf(do_select(curwind, bname));
}

BUFFER *
do_select(wp, name)
WINDOW	*wp;
char	*name;
{
	BUFFER	*new;

	new = mak_buf((char *) 0, name);
	if (wp)
		tiewind(wp, new);
	return new;
}

defb_wind(bp)
BUFFER *bp;
{
	WINDOW	*wp = fwind;

	do {
		if (wp->w_bufp == bp) {
			if (bp == curbuf)
				ignore(do_select(wp, Mainbuf));
			else {
				WINDOW	*save = wp->w_next;

				del_wind(wp);
				wp = save->w_prev;
			}
		}				
		wp = wp->w_next;
	} while (wp != fwind);
}

BUFFER *
AskBuf(prompt)
char	*prompt;
{
	BUFFER	*delbuf;
	char	*bname;

	bname = ask(curbuf->b_name, prompt);
	if (strcmp(bname, Mainbuf) == 0)
		return 0;
	delbuf = buf_exists(bname);
	if (delbuf == 0)
		complain("%s: no such buffer", bname);
	if (delbuf->b_modified)
		confirm("%s modified, are you sure? ", bname);
	return delbuf;
}

BufErase()
{
	BUFFER	*delbuf;

	if (delbuf = AskBuf(FuncName()))
		initlist(delbuf);
	SetUnmodified(delbuf);
}

BufKill()
{
	BUFFER	*delbuf;

	if ((delbuf = AskBuf(FuncName())) == 0)
		return;
	defb_wind(delbuf);
	if (curbuf == delbuf)
		SetBuf(curwind->w_bufp);
	lfreelist(delbuf->b_zero);
	delbuf->b_zero = 0;
	if (delbuf == lastbuf)
		lastbuf = curbuf;
}

BufList()
{
	char	format[40];
	int	bcount = 1;		/* To give each buffer a number */
	BUFFER	*bp;
	int	what;

	b_format(format);

	if (UseBuffers) {
		TellWBuffers("Buffer list", 0);
		curwind->w_bufp->b_type = SCRATCHBUF;
	} else
		TellWScreen(0);

	ignore(DoTell(sprint(format, "NO", "Buffer-type", "File-name", "Buffer-name", "")));
	ignore(DoTell(sprint(format, "--", "-----------", "---------", "-----------", "")));
	for (bp = world; bp; bp = bp->b_next) {
		if (bp->b_zero == 0)
			continue;
		what = DoTell(sprint(format, itoa(bcount++),
					bp->b_type == SCRATCHBUF ?
						"SCRATCH" : "FILE",
					filename(bp),
					bp->b_name,
					bufmod(bp)));
		if (what == ABORT || what == STOP)
			break;
	}
	if (UseBuffers) {
		Bof();		/* Go to the beginning of the file */
		NotModified();
	}
	StopTelling();
}

b_format(fmt)
char	*fmt;
{
	BUFFER	*bp;

	flen = 9;
	blen = 11;

	for (bp = world; bp; bp = bp->b_next) {
		flen = max(flen, (bp->b_fname ? strlen(bp->b_fname) : 0));
		blen = max(blen, strlen(bp->b_name));
	}
	ignore(sprintf(fmt, " %%-4s %%-11s  %%-%ds   %%-%ds  %%s", flen, blen));
}