1: /*************************************************************************
   2:  * This program is copyright (C) 1985, 1986 by Jonathan Payne.  It is    *
   3:  * provided to you without charge for use only on a licensed Unix        *
   4:  * system.  You may copy JOVE provided that this notice is included with *
   5:  * the copy.  You may not sell copies of this program or versions        *
   6:  * modified for use on microcomputer systems, unless the copies are      *
   7:  * included with a Unix system distribution and the source is provided.  *
   8:  *************************************************************************/
   9: 
  10: /* Contains commands that deal with creating, selecting, killing and
  11:    listing buffers, and buffer modes, and find-file, etc. */
  12: 
  13: #include "jove.h"
  14: 
  15: #include <sys/stat.h>
  16: 
  17: char    *Mainbuf = "Main",
  18:     *NoName = "Sans un nom!";
  19: 
  20: Buffer  *world = 0,     /* First in the list */
  21:     *curbuf = 0,
  22:     *lastbuf = 0;   /* Last buffer we were in so we have a default
  23: 			   buffer during a select buffer. */
  24: 
  25: /* Toggle BIT in the current buffer's minor mode flags.  If argument is
  26:    supplied, a positive one always turns on the mode and zero argument
  27:    always turns it off. */
  28: 
  29: TogMinor(bit)
  30: {
  31:     if (exp_p) {
  32:         if (exp == 0)
  33:             curbuf->b_minor &= ~bit;
  34:         else
  35:             curbuf->b_minor |= bit;
  36:     } else
  37:         curbuf->b_minor ^= bit;
  38:     UpdModLine++;
  39: }
  40: 
  41: /* Creates a new buffer, links it at the end of the buffer chain, and
  42:    returns it. */
  43: 
  44: static Buffer *
  45: buf_alloc()
  46: {
  47:     register Buffer *b,
  48:             *lastbp;
  49: 
  50:     lastbp = 0;
  51:     for (b = world; b != 0; lastbp = b, b = b->b_next)
  52:         ;
  53: 
  54:     b = (Buffer *) emalloc(sizeof (Buffer));
  55:     if (lastbp)
  56:         lastbp->b_next = b;
  57:     else
  58:         world = b;
  59:     b->b_first = 0;
  60:     b->b_next = 0;
  61: 
  62:     return b;
  63: }
  64: 
  65: /* Makes a buffer and initializes it.  Obsolete.  Used to take two
  66:    arguments, a buffer name and a file name. */
  67: 
  68: static Buffer *
  69: mak_buf()
  70: {
  71:     register Buffer *newb;
  72:     register int    i;
  73: 
  74:     newb = buf_alloc();
  75:     newb->b_fname = 0;
  76:     newb->b_name = NoName;
  77:     set_ino(newb);
  78:     newb->b_marks = 0;
  79:     newb->b_themark = 0;        /* Index into markring */
  80:     /* No marks yet */
  81:     for (i = 0; i < NMARKS; i++)
  82:         newb->b_markring[i] = 0;
  83:     newb->b_modified = 0;
  84:     newb->b_type = B_FILE;  /* File until proven SCRATCH */
  85:     newb->b_ntbf = 0;
  86:     newb->b_minor = 0;
  87:     newb->b_major = TEXT;
  88:     newb->b_first = 0;
  89:     initlist(newb);
  90:     return newb;
  91: }
  92: 
  93: ReNamBuf()
  94: {
  95:     register char   *new = 0,
  96:             *prompt = ProcFmt,
  97:             *second = "%s already exists; new name? ";
  98: 
  99:     for (;;) {
 100:         new = ask((char *) 0, prompt, new);
 101:         if (!buf_exists(new))
 102:             break;
 103:         prompt = second;
 104:     }
 105:     setbname(curbuf, new);
 106: }
 107: 
 108: FindFile()
 109: {
 110:     register char   *name;
 111:     char    fnamebuf[FILESIZE];
 112: 
 113:     name = ask_file(curbuf->b_fname, fnamebuf);
 114:     SetABuf(curbuf);
 115:     SetBuf(do_find(curwind, name, 0));
 116: }
 117: 
 118: static
 119: mkbuflist(bnamp)
 120: register char   **bnamp;
 121: {
 122:     register Buffer *b;
 123: 
 124:     for (b = world; b != 0; b = b->b_next)
 125:         if (b->b_name != 0)
 126:             *bnamp++ = b->b_name;
 127:     *bnamp = 0;
 128: }
 129: 
 130: char *
 131: ask_buf(def)
 132: Buffer  *def;
 133: {
 134:     char    *bnames[100];
 135:     register char   *bname;
 136:     register int    offset;
 137:     char    prompt[100];
 138: 
 139:     if (def != 0 && def->b_name != 0)
 140:         sprintf(prompt, ": %f (default %s) ", def->b_name);
 141:     else
 142:         sprintf(prompt, ProcFmt);
 143:     mkbuflist(bnames);
 144:     offset = complete(bnames, prompt, RET_STATE);
 145:     if (offset == EOF)
 146:         complain((char *) 0);
 147:     if (offset == ORIGINAL)
 148:         bname = Minibuf;
 149:     else if (offset == NULLSTRING) {
 150:         if (def)
 151:             bname = def->b_name;
 152:         else
 153:             complain((char *) 0);
 154:     } else if (offset < 0)
 155:         complain((char *) 0);
 156:     else
 157:         bname = bnames[offset];
 158: 
 159:     return bname;
 160: }
 161: 
 162: BufSelect()
 163: {
 164:     register char   *bname;
 165: 
 166:     bname = ask_buf(lastbuf);
 167:     SetABuf(curbuf);
 168:     SetBuf(do_select(curwind, bname));
 169: }
 170: 
 171: static
 172: defb_wind(b)
 173: register Buffer *b;
 174: {
 175:     register Window *w = fwind;
 176:     char    *alt;
 177: 
 178:     if (lastbuf == b || lastbuf == 0) {
 179:         lastbuf = 0;
 180:         alt = (b->b_next != 0) ? b->b_next->b_name : Mainbuf;
 181:     } else
 182:         alt = lastbuf->b_name;
 183: 
 184:     do {
 185:         if (w->w_bufp == b) {
 186:             if (one_windp())
 187:                 (void) do_select(w, alt);
 188:             else {
 189:                 register Window *save = w->w_next;
 190: 
 191:                 del_wind(w);
 192:                 w = save->w_prev;
 193:             }
 194:         }
 195:         w = w->w_next;
 196:     } while (w != fwind);
 197: }
 198: 
 199: Buffer *
 200: getNMbuf()
 201: {
 202:     register Buffer *delbuf;
 203:     register char   *bname;
 204: 
 205:     bname = ask_buf(curbuf);
 206:     if ((delbuf = buf_exists(bname)) == 0)
 207:         complain("[No such buffer]");
 208:     if (delbuf->b_modified)
 209:         confirm("%s modified, are you sure? ", bname);
 210:     return delbuf;
 211: }
 212: 
 213: BufErase()
 214: {
 215:     register Buffer *delbuf;
 216: 
 217:     if (delbuf = getNMbuf()) {
 218:         initlist(delbuf);
 219:         delbuf->b_modified = 0;
 220:     }
 221: }
 222: 
 223: static
 224: kill_buf(delbuf)
 225: register Buffer *delbuf;
 226: {
 227:     register Buffer *b,
 228:             *lastb = 0;
 229:     extern Buffer   *perr_buf;
 230: 
 231: #ifdef IPROCS
 232:     pbuftiedp(delbuf);  /* Make sure buffer is not tied to a process */
 233: #endif
 234:     for (b = world; b != 0; lastb = b, b = b->b_next)
 235:         if (b == delbuf)
 236:             break;
 237:     if (lastb)
 238:         lastb->b_next = delbuf->b_next;
 239:     else
 240:         world = delbuf->b_next;
 241: 
 242: #define okay_free(ptr)  if (ptr) free(ptr)
 243: 
 244:     lfreelist(delbuf->b_first);
 245:     okay_free(delbuf->b_name);
 246:     okay_free(delbuf->b_fname);
 247:     free((char *) delbuf);
 248: 
 249:     if (delbuf == lastbuf)
 250:         SetABuf(curbuf);
 251:     if (perr_buf == delbuf) {
 252:         ErrFree();
 253:         perr_buf = 0;
 254:     }
 255:     defb_wind(delbuf);
 256:     if (curbuf == delbuf)
 257:         SetBuf(curwind->w_bufp);
 258: }
 259: 
 260: /* offer to kill some buffers */
 261: 
 262: KillSome()
 263: {
 264:     register Buffer *b,
 265:             *next;
 266:     Buffer  *oldb;
 267:     register char   *y_or_n;
 268: 
 269:     for (b = world; b != 0; b = next) {
 270:         next = b->b_next;
 271:         y_or_n = ask("No", "Kill %s? ", b->b_name);
 272:         if (Upper(*y_or_n) != 'Y')
 273:             continue;
 274:         if (IsModified(b)) {
 275:             y_or_n = ask("No", "%s modified; should I save it? ", b->b_name);
 276:             if (Upper(*y_or_n) == 'Y') {
 277:                 oldb = curbuf;
 278:                 SetBuf(b);
 279:                 SaveFile();
 280:                 SetBuf(oldb);
 281:             }
 282:         }
 283:         kill_buf(b);
 284:     }
 285: }
 286: 
 287: BufKill()
 288: {
 289:     Buffer  *b;
 290: 
 291:     if ((b = getNMbuf()) == 0)
 292:         return;
 293:     kill_buf(b);
 294: }
 295: 
 296: static char *
 297: line_cnt(b, buf)
 298: register Buffer *b;
 299: char    *buf;
 300: {
 301:     register int    nlines = 0;
 302:     register Line   *lp;
 303: 
 304:     for (lp = b->b_first; lp != 0; lp = lp->l_next, nlines++)
 305:         ;
 306:     sprintf(buf, "%d", nlines);
 307:     return buf;
 308: }
 309: 
 310: static char *TypeNames[] = {
 311:     0,
 312:     "Scratch",
 313:     "File",
 314:     "Process",
 315:     "I-process"
 316: };
 317: 
 318: BufList()
 319: {
 320:     register char   *format = "%-2s %-5s %-11s %-1s %-*s  %-s";
 321:     register Buffer *b;
 322:     int bcount = 1,     /* To give each buffer a number */
 323:         buf_width = 11;
 324:     char    nbuf[10];
 325:     extern int  ModCount;
 326: 
 327:     for (b = world; b != 0; b = b->b_next)
 328:         buf_width = max(buf_width, strlen(b->b_name));
 329: 
 330:     TOstart("Buffer list", TRUE);   /* true means auto-newline */
 331: 
 332:     Typeout("(* means buffer needs saving)");
 333:     Typeout("(+ means file hasn't been read yet)");
 334:     Typeout(NullStr);
 335:     Typeout(format, "NO", "Lines", "Type", NullStr, buf_width, "Name", "File");
 336:     Typeout(format, "--", "-----", "----", NullStr, buf_width, "----", "----");
 337:     for (b = world; b != 0; b = b->b_next) {
 338:         Typeout(format, itoa(bcount++),
 339:                 line_cnt(b, nbuf),
 340:                 TypeNames[b->b_type],
 341:                 IsModified(b) ? "*" :
 342:                      b->b_ntbf ? "+" : NullStr,
 343:                 buf_width,
 344:                 /* For the * (variable length field) */
 345:                 b->b_name,
 346:                 filename(b));
 347: 
 348:         if (TOabort)
 349:             break;
 350:     }
 351:     TOstop();
 352: }
 353: 
 354: bufname(b)
 355: register Buffer *b;
 356: {
 357:     char    tmp[100],
 358:         *cp;
 359:     int try = 1;
 360: 
 361:     if (b->b_fname == 0)
 362:         complain("[No file name]");
 363:     cp = basename(b->b_fname);
 364:     strcpy(tmp, cp);
 365:     while (buf_exists(tmp)) {
 366:         sprintf(tmp, "%s.%d", cp, try);
 367:         try++;
 368:     }
 369:     setbname(b, tmp);
 370: }
 371: 
 372: initlist(b)
 373: register Buffer *b;
 374: {
 375:     lfreelist(b->b_first);
 376:     b->b_first = b->b_dot = b->b_last = 0;
 377:     (void) listput(b, b->b_first);
 378: 
 379:     SavLine(b->b_dot, NullStr);
 380:     b->b_char = 0;
 381:     AllMarkSet(b, b->b_dot, 0);
 382:     if (b == curbuf)
 383:         getDOT();
 384: }
 385: 
 386: /* Returns pointer to buffer with name NAME, or if NAME is a string of digits
 387:    returns the buffer whose number equals those digits.  Otherwise, returns
 388:    0. */
 389: 
 390: Buffer *
 391: buf_exists(name)
 392: register char   *name;
 393: {
 394:     register Buffer *bp;
 395:     register int    n;
 396: 
 397:     if (name == 0)
 398:         return 0;
 399: 
 400:     for (bp = world; bp != 0; bp = bp->b_next)
 401:         if (strcmp(bp->b_name, name) == 0)
 402:             return bp;
 403: 
 404:     /* Doesn't match any names.  Try for a buffer number... */
 405: 
 406:     if ((n = chr_to_int(name, 10, 1)) > 0) {
 407:         for (bp = world; n > 1; bp = bp->b_next) {
 408:             if (bp == 0)
 409:                 break;
 410:             --n;
 411:         }
 412:         return bp;
 413:     }
 414: 
 415:     return 0;
 416: }
 417: 
 418: /* Returns buffer pointer with a file name NAME, if one exists.  Stat's the
 419:    file and compares inodes, in case NAME is a link, as well as the actual
 420:    characters that make up the file name. */
 421: 
 422: Buffer *
 423: file_exists(name)
 424: register char   *name;
 425: {
 426:     struct stat stbuf;
 427:     register struct stat    *s = &stbuf;
 428:     register Buffer *b = 0;
 429:     char    fnamebuf[FILESIZE];
 430: 
 431:     if (name) {
 432:         PathParse(name, fnamebuf);
 433:         if (stat(fnamebuf, s) == -1)
 434:             s->st_ino = 0;
 435:         for (b = world; b != 0; b = b->b_next) {
 436:             if ((b->b_ino != 0 && b->b_ino == s->st_ino) ||
 437:                 (strcmp(b->b_fname, fnamebuf) == 0))
 438:                 break;
 439:         }
 440:     }
 441:     return b;
 442: }
 443: 
 444: char *
 445: ralloc(obj, size)
 446: register char   *obj;
 447: {
 448:     register char   *new;
 449: 
 450:     if (obj)
 451:         new = realloc(obj, (unsigned) size);
 452:     if (new == 0 || !obj)
 453:         new = emalloc(size);
 454:     return new;
 455: }
 456: 
 457: setbname(b, name)
 458: register Buffer *b;
 459: register char   *name;
 460: {
 461:     UpdModLine++;   /* Kludge ... but speeds things up considerably */
 462:     if (name) {
 463:         if (b->b_name == NoName)
 464:             b->b_name = 0;
 465:         b->b_name = ralloc(b->b_name, strlen(name) + 1);
 466:         strcpy(b->b_name, name);
 467:     } else
 468:         b->b_name = 0;
 469: }
 470: 
 471: setfname(b, name)
 472: register Buffer *b;
 473: register char   *name;
 474: {
 475:     char    wholename[FILESIZE],
 476:         oldname[FILESIZE],
 477:         *oldptr = oldname;
 478:     Buffer  *save = curbuf;
 479: 
 480:     SetBuf(b);
 481:     UpdModLine++;   /* Kludge ... but speeds things up considerably */
 482:     if (b->b_fname == 0)
 483:         oldptr = 0;
 484:     else
 485:         strcpy(oldname, b->b_fname);
 486:     if (name) {
 487:         PathParse(name, wholename);
 488:         curbuf->b_fname = ralloc(curbuf->b_fname, strlen(wholename) + 1);
 489:         strcpy(curbuf->b_fname, wholename);
 490:     } else
 491:         b->b_fname = 0;
 492:     DoAutoExec(curbuf->b_fname, oldptr);
 493:     curbuf->b_mtime = curbuf->b_ino = 0;    /* until they're known. */
 494:     SetBuf(save);
 495: }
 496: 
 497: set_ino(b)
 498: register Buffer *b;
 499: {
 500:     struct stat stbuf;
 501: 
 502:     if (b->b_fname == 0 || stat(b->b_fname, &stbuf) == -1) {
 503:         b->b_ino = 0;
 504:         b->b_mtime = 0;
 505:     } else {
 506:         b->b_ino = stbuf.st_ino;
 507:         b->b_mtime = stbuf.st_mtime;
 508:     }
 509: }
 510: 
 511: /* Find the file `fname' into buf and put in in window `w' */
 512: 
 513: Buffer *
 514: do_find(w, fname, force)
 515: register Window *w;
 516: register char   *fname;
 517: {
 518:     register Buffer *b;
 519: 
 520:     b = file_exists(fname);
 521:     if (b == 0) {
 522:         b = mak_buf();
 523:         setfname(b, fname);
 524:         bufname(b);
 525:         set_ino(b);
 526:         b->b_ntbf = 1;
 527:         if (force) {
 528:             Buffer  *oldb = curbuf;
 529: 
 530:             SetBuf(b);  /* this'll read the file */
 531:             SetBuf(oldb);
 532:         }
 533:     }
 534:     if (w)
 535:         tiewind(w, b);
 536:     return b;
 537: }
 538: 
 539: /* Set alternate buffer */
 540: 
 541: SetABuf(b)
 542: Buffer  *b;
 543: {
 544:     if (b != 0)
 545:         lastbuf = b;
 546: }
 547: 
 548: SetBuf(newbuf)
 549: register Buffer *newbuf;
 550: {
 551:     register Buffer *oldb = curbuf;
 552: 
 553:     if (newbuf == curbuf || newbuf == 0)
 554:         return;
 555: 
 556:     lsave();
 557:     curbuf = newbuf;
 558:     getDOT();
 559:     /* Do the read now ... */
 560:     if (curbuf->b_ntbf)
 561:         read_file(curbuf->b_fname, 0);
 562: 
 563: #ifdef IPROCS
 564:     if (oldb != 0 && oldb->b_type != curbuf->b_type) {
 565:         if (curbuf->b_type == B_IPROCESS)
 566:             PushPBs();      /* Push process bindings */
 567:         else if (oldb->b_type == B_IPROCESS)
 568:             PopPBs();
 569:     }
 570:     assign_p();     /* Set cur_proc */
 571: #endif
 572: }
 573: 
 574: Buffer *
 575: do_select(w, name)
 576: register Window *w;
 577: register char   *name;
 578: {
 579:     register Buffer *new;
 580: 
 581:     if ((new = buf_exists(name)) == 0) {
 582:         new = mak_buf();
 583:         setfname(new, (char *) 0);
 584:         setbname(new, name);
 585:     }
 586:     if (w)
 587:         tiewind(w, new);
 588:     return new;
 589: }

Defined functions

BufErase defined in line 213; used 2 times
BufKill defined in line 287; used 2 times
BufList defined in line 318; used 2 times
BufSelect defined in line 162; used 4 times
FindFile defined in line 108; used 4 times
KillSome defined in line 262; used 2 times
ReNamBuf defined in line 93; used 2 times
SetABuf defined in line 541; used 5 times
TogMinor defined in line 29; used 1 times
ask_buf defined in line 130; used 5 times
buf_alloc defined in line 44; used 1 times
  • in line 74
bufname defined in line 354; used 1 times
defb_wind defined in line 171; used 1 times
do_find defined in line 513; used 6 times
file_exists defined in line 422; used 3 times
getNMbuf defined in line 199; used 2 times
initlist defined in line 372; used 5 times
kill_buf defined in line 223; used 2 times
line_cnt defined in line 296; used 1 times
mak_buf defined in line 68; used 2 times
mkbuflist defined in line 118; used 1 times
ralloc defined in line 444; used 4 times
set_ino defined in line 497; used 4 times
setbname defined in line 457; used 3 times
setfname defined in line 471; used 5 times

Defined variables

Mainbuf defined in line 17; used 1 times
TypeNames defined in line 310; used 1 times
world defined in line 20; used 11 times

Defined macros

okay_free defined in line 242; used 2 times
Last modified: 1986-03-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1935
Valid CSS Valid XHTML 1.0 Strict