|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.