home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
gnu
/
src
/
baseline
/
jove-4.14.6.lha
/
jove-4.14.6
/
buf.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-10
|
14KB
|
721 lines
/***************************************************************************
* 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>
#endif
private 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. */
void
TogMinor(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;
}
void
ReNamBuf()
{
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);
}
void
FindFile()
{
register char *name;
char fnamebuf[FILESIZE];
name = ask_file((char *)NULL, curbuf->b_fname, fnamebuf);
SetABuf(curbuf);
SetBuf(do_find(curwind, name, NO));
}
private void
mkbuflist(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;
}
void
BufSelect()
{
register char *bname;
bname = ask_buf(lastbuf);
SetABuf(curbuf);
SetBuf(do_select(curwind, bname));
}
#ifdef MSDOS
private void
BufNSelect(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 void
defb_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;
}
void
BufErase()
{
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 void
kill_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 */
void
KillSome()
{
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);
}
}
void
BufKill()
{
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",
};
void
BufList()
{
register char *fmt = "%-2s %-5