/* 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 #include 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)); }