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

Defined functions

Buf10Select defined in line 250; used 4 times
Buf1Select defined in line 241; used 4 times
Buf2Select defined in line 242; used 4 times
Buf3Select defined in line 243; used 4 times
Buf4Select defined in line 244; used 4 times
Buf5Select defined in line 245; used 4 times
Buf6Select defined in line 246; used 4 times
Buf7Select defined in line 247; used 4 times
Buf8Select defined in line 248; used 4 times
Buf9Select defined in line 249; used 4 times
BufErase defined in line 295; used 4 times
BufKill defined in line 378; used 4 times
BufList defined in line 409; used 4 times
BufNSelect defined in line 225; used 12 times
KillSome defined in line 353; used 4 times
ReNamBuf defined in line 142; used 4 times
TogMinor defined in line 67; used 3 times
buf_alloc defined in line 83; used 3 times
bufname defined in line 445; used 4 times
defb_wind defined in line 254; used 3 times
file_exists defined in line 515; used 5 times
getNMbuf defined in line 281; used 4 times
kill_buf defined in line 306; used 4 times
line_cnt defined in line 388; used 3 times
mak_buf defined in line 110; used 4 times
mkbuflist defined in line 169; used 4 times
ralloc defined in line 544; used 6 times
set_ino defined in line 608; used 6 times
setbname defined in line 557; used 5 times
setfname defined in line 575; used 7 times
valid_bp defined in line 665; used 1 times

Defined variables

Mainbuf defined in line 55; used 2 times
TypeNames defined in line 402; used 1 times
private defined in line 388; never used
world defined in line 58; used 12 times

Defined macros

okay_free defined in line 327; used 2 times
private defined in line 52; used 9 times
Last modified: 1988-03-22
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4441
Valid CSS Valid XHTML 1.0 Strict