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 >
C/C++ Source or Header  |  1992-01-10  |  14KB  |  721 lines

  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. #include "ctype.h"
  13. #include "disp.h"
  14. #ifdef    IPROCS
  15. # include "fp.h"
  16. # include "iproc.h"
  17. #endif
  18.  
  19. #ifdef    MAC
  20. # include "mac.h"
  21. #else
  22. # include <sys/stat.h>
  23. #endif
  24.  
  25. private void
  26.     setbname proto((Buffer *, char *));
  27.  
  28. private char    *Mainbuf = "Main",
  29.     *NoName = "Sans un nom!";
  30.  
  31. Buffer    *world = NULL,        /* First in the list */
  32.     *curbuf = NULL,        /* pointer into world for current buffer */
  33.     *lastbuf = NULL;    /* Last buffer we were in so we have a default
  34.                    buffer during a select buffer. */
  35.  
  36. /* Toggle BIT in the current buffer's minor mode flags.  If argument is
  37.    supplied, a positive one always turns on the mode and zero argument
  38.    always turns it off. */
  39.  
  40. void
  41. TogMinor(bit)
  42. int    bit;
  43. {
  44.     if (is_an_arg()) {
  45.         if (arg_value() == 0)
  46.             curbuf->b_minor &= ~bit;
  47.         else
  48.             curbuf->b_minor |= bit;
  49.     } else
  50.         curbuf->b_minor ^= bit;
  51.     UpdModLine = YES;
  52. }
  53.  
  54. /* Creates a new buffer, links it at the end of the buffer chain, and
  55.    returns it. */
  56.  
  57. private Buffer    *free_bufs = NULL;
  58.  
  59. private Buffer *
  60. buf_alloc()
  61. {
  62.     register Buffer    *b,
  63.             *lastbp;
  64.  
  65.     lastbp = NULL;
  66.     for (b = world; b != NULL; b = b->b_next)
  67.         lastbp = b;
  68.  
  69.     if (free_bufs != NULL) {
  70.         b = free_bufs;
  71.         free_bufs = b->b_next;
  72.     } else {
  73.         b = (Buffer *) emalloc(sizeof (Buffer));
  74.     }
  75.     if (lastbp)
  76.         lastbp->b_next = b;
  77.     else
  78.         world = b;
  79.     b->b_first = NULL;
  80.     b->b_next = NULL;
  81. #ifdef    MAC
  82.     b->Type = BUFFER;    /* kludge, but simplifies menu handlers */
  83.     b->Name = NULL;
  84. #endif
  85.     return b;
  86. }
  87.  
  88. /* Makes a buffer and initializes it.  Obsolete.  Used to take two
  89.    arguments, a buffer name and a file name. */
  90.  
  91. private Buffer *
  92. mak_buf()
  93. {
  94.     register Buffer    *newb;
  95.     register int    i;
  96.  
  97.     newb = buf_alloc();
  98.     newb->b_fname = NULL;
  99.     newb->b_name = NoName;
  100.     set_ino(newb);
  101.     newb->b_marks = NULL;
  102.     newb->b_themark = 0;        /* Index into markring */
  103.     /* No marks yet */
  104.     for (i = 0; i < NMARKS; i++)
  105.         newb->b_markring[i] = NULL;
  106.     newb->b_modified = NO;
  107.     newb->b_type = B_FILE;  /* File until proven SCRATCH */
  108.     newb->b_ntbf = NO;
  109.     newb->b_minor = 0;
  110.     newb->b_major = TEXT;
  111.     newb->b_first = NULL;
  112.     newb->b_map = NULL;
  113. #ifdef    IPROCS
  114.     newb->b_process = NULL;
  115. #endif
  116.     initlist(newb);
  117. #ifdef    MAC
  118.     Bufchange = YES;
  119. #endif
  120.     return newb;
  121. }
  122.  
  123. void
  124. ReNamBuf()
  125. {
  126.     register char    *new = NULL,
  127.             *prompt = ProcFmt,
  128.             *second = "%s already exists; new name? ";
  129.  
  130.     for (;;) {
  131.         new = ask((char *)NULL, prompt, new);
  132.         if (!buf_exists(new))
  133.             break;
  134.         prompt = second;
  135.     }
  136.     setbname(curbuf, new);
  137. }
  138.  
  139. void
  140. FindFile()
  141. {
  142.     register char    *name;
  143.     char    fnamebuf[FILESIZE];
  144.  
  145.     name = ask_file((char *)NULL, curbuf->b_fname, fnamebuf);
  146.     SetABuf(curbuf);
  147.     SetBuf(do_find(curwind, name, NO));
  148. }
  149.  
  150. private void
  151. mkbuflist(bnamp, ebnamp)
  152. register char    **bnamp;
  153. char        **ebnamp;
  154. {
  155.     register Buffer    *b;
  156.  
  157.     for (b = world; b != NULL; b = b->b_next) {
  158.         if (b->b_name != NULL) {
  159.             *bnamp++ = b->b_name;
  160.             if (bnamp >= ebnamp)
  161.                 complain("too many buffers to list");
  162.         }
  163.     }
  164.     *bnamp = NULL;
  165. }
  166.  
  167. char *
  168. ask_buf(def)
  169. Buffer    *def;
  170. {
  171.     char    *bnames[100];
  172.     register char    *bname;
  173.     register int    offset;
  174.     char    prompt[100];
  175.  
  176.     if (def != NULL && def->b_name != NULL) {
  177.         swritef(prompt, sizeof(prompt), ": %f (default %s) ",
  178.             def->b_name);
  179.     } else {
  180.         swritef(prompt, sizeof(prompt), ProcFmt);
  181.     }
  182.     mkbuflist(bnames, &bnames[sizeof(bnames) / sizeof(*bnames)]);
  183.     offset = complete(bnames, prompt, RET_STATE);
  184.     if (offset == EOF)
  185.         complain((char *)NULL);
  186.     if (offset == ORIGINAL || offset == AMBIGUOUS) {
  187.         bname = Minibuf;
  188.     } else if (offset == NULLSTRING) {
  189.         if (def == NULL)
  190.             complain((char *)NULL);
  191.         bname = def->b_name;
  192.     } else {
  193.         if (offset < 0)
  194.             complain((char *)NULL);
  195.         bname = bnames[offset];
  196.     }
  197.  
  198.     return bname;
  199. }
  200.  
  201. void
  202. BufSelect()
  203. {
  204.     register char    *bname;
  205.  
  206.     bname = ask_buf(lastbuf);
  207.     SetABuf(curbuf);
  208.     SetBuf(do_select(curwind, bname));
  209. }
  210.  
  211. #ifdef    MSDOS
  212.  
  213. private void
  214. BufNSelect(n)
  215. int    n;
  216. {
  217.     register Buffer    *b;
  218.  
  219.     for (b = world; b != NULL; b = b->b_next) {
  220.         if (b->b_name != NULL) {
  221.             if (n == 0) {
  222.                 SetABuf(curbuf);
  223.                 SetBuf(do_select(curwind, b->b_name));
  224.                 return;
  225.             }
  226.             n -= 1;
  227.         }
  228.     }
  229.     complain("[No such buffer]");
  230. }
  231.  
  232. void Buf0Select() { BufNSelect(0); }
  233. void Buf1Select() { BufNSelect(1); }
  234. void Buf2Select() { BufNSelect(2); }
  235. void Buf3Select() { BufNSelect(3); }
  236. void Buf4Select() { BufNSelect(4); }
  237. void Buf5Select() { BufNSelect(5); }
  238. void Buf6Select() { BufNSelect(6); }
  239. void Buf7Select() { BufNSelect(7); }
  240. void Buf8Select() { BufNSelect(8); }
  241. void Buf9Select() { BufNSelect(9); }
  242.  
  243. #endif    /* MSDOS */
  244.  
  245. private void
  246. defb_wind(b)
  247. register Buffer *b;
  248. {
  249.     register Window    *w = fwind;
  250.     char    *alt;
  251.  
  252.     if (lastbuf == b || lastbuf == NULL) {
  253.         lastbuf = NULL;
  254.         alt = (b->b_next != NULL) ? b->b_next->b_name : Mainbuf;
  255.     } else
  256.         alt = lastbuf->b_name;
  257.  
  258.     do {
  259.         if (w->w_bufp == b) {
  260.             if (one_windp() || alt != Mainbuf)
  261.                 (void) do_select(w, alt);
  262.             else {
  263.                 Window    *save = w->w_next;
  264.  
  265.                 del_wind(w);
  266.                 w = save->w_prev;
  267.             }
  268.         }
  269.         w = w->w_next;
  270.     } while (w != fwind || w->w_bufp == b);
  271. }
  272.  
  273. private Buffer *
  274. getNMbuf()
  275. {
  276.     register Buffer    *delbuf;
  277.     register char    *bname;
  278.  
  279.     bname = ask_buf(curbuf);
  280.     if ((delbuf = buf_exists(bname)) == NULL)
  281.         complain("[No such buffer]");
  282.     if (delbuf->b_modified)
  283.         confirm("%s modified, are you sure? ", bname);
  284.     return delbuf;
  285. }
  286.  
  287. void
  288. BufErase()
  289. {
  290.     register Buffer    *delbuf;
  291.  
  292.     if ((delbuf = getNMbuf()) != NULL) {
  293.         initlist(delbuf);
  294.         delbuf->b_modified = NO;
  295.     }
  296. }
  297.  
  298. /* Free a buffer structure.
  299.  * The actual struct is preserved to reduce the damage
  300.  * from dangling references to it.  They seem to be pervasive.
  301.  * We try to reset enough that a dangling reference will be useless.
  302.  */
  303.  
  304. private void
  305. kill_buf(delbuf)
  306. register Buffer    *delbuf;
  307. {
  308.     register Buffer    *b,
  309.             *lastb = NULL;
  310.  
  311. #ifdef    IPROCS
  312.     pbuftiedp(delbuf);    /* check for lingering processes */
  313. #endif
  314.     /* clean up windows associated with this buffer */
  315.     if (delbuf == curbuf)
  316.         curbuf = NULL;
  317.     if (delbuf == lastbuf)
  318.         lastbuf = curbuf;    /* even if NULL */
  319.     defb_wind(delbuf);
  320.     if (curbuf == NULL)
  321.         SetBuf(curwind->w_bufp);
  322.  
  323.     /* unlink the buffer */
  324.     for (b = world; b != NULL; lastb = b, b = b->b_next)
  325.         if (b == delbuf)
  326.             break;
  327.     if (lastb)
  328.         lastb->b_next = delbuf->b_next;
  329.     else
  330.         world = delbuf->b_next;
  331.  
  332. #ifndef    MAC
  333.     if (perr_buf == delbuf) {
  334.         ErrFree();
  335.         perr_buf = NULL;
  336.     }
  337. #endif
  338.  
  339.     lfreelist(delbuf->b_first);
  340.     delbuf->b_first = delbuf->b_dot = delbuf->b_last = NULL;
  341.     if (delbuf->b_name) {
  342.         free((UnivPtr) delbuf->b_name);
  343.         delbuf->b_name = NULL;
  344.     }
  345.     if (delbuf->b_fname) {
  346.         free((UnivPtr) delbuf->b_fname);
  347.         delbuf->b_fname = NULL;
  348.     }
  349.     flush_marks(delbuf);
  350.     delbuf->b_marks = NULL;
  351.  
  352.     delbuf->b_next = free_bufs;
  353.     free_bufs = delbuf;
  354. #ifdef    MAC
  355.     Bufchange = YES;
  356.     delbuf->Name = NULL;
  357. #endif
  358. }
  359.  
  360. /* offer to kill some buffers */
  361.  
  362. void
  363. KillSome()
  364. {
  365.     register Buffer    *b,
  366.             *next;
  367.     Buffer    *oldb;
  368.     register char    *y_or_n;
  369.  
  370.     for (b = world; b != NULL; b = next) {
  371.         next = b->b_next;
  372.         if (yes_or_no_p("Kill %s? ", b->b_name) == NO)
  373.             continue;
  374.         if (IsModified(b)) {
  375.             y_or_n = ask("No", "%s modified; should I save it? ", b->b_name);
  376.             if (CharUpcase(*y_or_n) == 'Y') {
  377.                 oldb = curbuf;
  378.                 SetBuf(b);
  379.                 SaveFile();
  380.                 SetBuf(oldb);
  381.             }
  382.         }
  383.         kill_buf(b);
  384.     }
  385. }
  386.  
  387. void
  388. BufKill()
  389. {
  390.     Buffer    *b;
  391.  
  392.     if ((b = getNMbuf()) == NULL)
  393.         return;
  394.     kill_buf(b);
  395. }
  396.  
  397. private char *
  398. line_cnt(b, buf, size)
  399. register Buffer    *b;
  400. char    *buf;
  401. size_t    size;
  402. {
  403.     register int    nlines = 0;
  404.     register Line    *lp;
  405.  
  406.     for (lp = b->b_first; lp != NULL; lp = lp->l_next, nlines++)
  407.         ;
  408.     swritef(buf, size, "%d", nlines);
  409.     return buf;
  410. }
  411.  
  412. private const char    *const TypeNames[] = {
  413.     NULL,
  414.     "Scratch",
  415.     "File",
  416.     "Process",
  417. };
  418.  
  419. void
  420. BufList()
  421. {
  422.     register char    *fmt = "%-2s %-5