fileio.c
上传用户:gddssl
上传日期:2007-01-06
资源大小:1003k
文件大小:110k
源码类别:

编辑器/阅读器

开发平台:

DOS

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8. /*
  9.  * fileio.c: read from and write to a file
  10.  */
  11. #if defined(MSDOS) || defined(WIN32)
  12. # include <io.h> /* for lseek(), must be before vim.h */
  13. #endif
  14. #if defined __EMX__
  15. # include <io.h> /* for mktemp(), CJW 1997-12-03 */
  16. #endif
  17. #include "vim.h"
  18. #ifdef HAVE_FCNTL_H
  19. # include <fcntl.h>
  20. #endif
  21. #ifdef LATTICE
  22. # include <proto/dos.h>     /* for Lock() and UnLock() */
  23. #endif
  24. #define BUFSIZE     8192     /* size of normal write buffer */
  25. #define SMBUFSIZE    256     /* size of emergency write buffer */
  26. #ifdef VIMINFO
  27. static void check_marks_read __ARGS((void));
  28. #endif
  29. #ifdef UNIX
  30. static void set_file_time __ARGS((char_u *fname, time_t atime, time_t mtime));
  31. #endif
  32. static void msg_add_fname __ARGS((BUF *, char_u *));
  33. static int msg_add_fileformat __ARGS((int eol_type));
  34. static void msg_add_lines __ARGS((int, long, long));
  35. static void msg_add_eol __ARGS((void));
  36. static int check_mtime __ARGS((BUF *buf, struct stat *s));
  37. static int  write_buf __ARGS((int, char_u *, int));
  38. static linenr_t write_no_eol_lnum = 0; /* non-zero lnum when last line of
  39.    next binary write should not have
  40.    an end-of-line */
  41.     void
  42. filemess(buf, name, s, attr)
  43.     BUF *buf;
  44.     char_u *name;
  45.     char_u *s;
  46.     int attr;
  47. {
  48.     int msg_scroll_save;
  49.     msg_add_fname(buf, name);     /* put file name in IObuff with quotes */
  50.     STRCAT(IObuff, s);
  51.     /*
  52.      * For the first message may have to start a new line.
  53.      * For further ones overwrite the previous one, reset msg_scroll before
  54.      * calling filemess().
  55.      */
  56.     msg_scroll_save = msg_scroll;
  57.     if (shortmess(SHM_OVERALL))
  58. msg_scroll = FALSE;
  59.     msg_start();
  60.     msg_scroll = msg_scroll_save;
  61.     msg_outtrans_attr(IObuff, attr);
  62.     msg_clr_eos();
  63.     out_flush();
  64. }
  65. /*
  66.  * Read lines from file 'fname' into the buffer after line 'from'.
  67.  *
  68.  * 1. We allocate blocks with lalloc, as big as possible.
  69.  * 2. Each block is filled with characters from the file with a single read().
  70.  * 3. The lines are inserted in the buffer with ml_append().
  71.  *
  72.  * (caller must check that fname != NULL, unless READ_STDIN is used)
  73.  *
  74.  * lines_to_skip is the number of lines that must be skipped
  75.  * lines_to_read is the number of lines that are appended
  76.  * When not recovering lines_to_skip is 0 and lines_to_read MAXLNUM.
  77.  *
  78.  * flags:
  79.  * READ_NEW starting to edit a new buffer
  80.  * READ_FILTER reading filter output
  81.  * READ_STDIN read from stdin instead of a file
  82.  *
  83.  * return FAIL for failure, OK otherwise
  84.  */
  85.     int
  86. readfile(fname, sfname, from, lines_to_skip, lines_to_read, flags)
  87.     char_u *fname;
  88.     char_u *sfname;
  89.     linenr_t from;
  90.     linenr_t lines_to_skip;
  91.     linenr_t lines_to_read;
  92.     int flags;
  93. {
  94.     int fd;
  95.     int newfile = (flags & READ_NEW);
  96.     int check_readonly;
  97.     int filtering = (flags & READ_FILTER);
  98.     int read_stdin = (flags & READ_STDIN);
  99.     char_u c;
  100.     linenr_t lnum = from;
  101.     char_u *ptr = NULL; /* pointer into read buffer */
  102.     char_u *buffer = NULL; /* read buffer */
  103.     char_u *new_buffer = NULL; /* init to shut up gcc */
  104.     char_u *line_start = NULL; /* init to shut up gcc */
  105.     int wasempty; /* buffer was empty before reading */
  106.     colnr_t len;
  107.     long size;
  108.     char_u *p;
  109.     long filesize;
  110.     int split = 0; /* number of split lines */
  111. #define UNKNOWN  0x0fffffff /* file size is unknown */
  112.     linenr_t linecnt;
  113.     int error = FALSE; /* errors encountered */
  114.     int ff_error = EOL_UNKNOWN; /* file format with errors */
  115.     long linerest; /* remaining chars in line */
  116.     int perm = 0;
  117.     int fileformat; /* end-of-line format */
  118.     struct stat st;
  119.     int file_readonly;
  120.     linenr_t skip_count;
  121.     linenr_t read_count;
  122.     int msg_save = msg_scroll;
  123.     linenr_t read_no_eol_lnum = 0;   /* non-zero lnum when last line of
  124.  * last read was missing the eol */
  125.     int try_mac = (vim_strchr(p_ffs, 'm') != NULL);
  126.     int try_dos = (vim_strchr(p_ffs, 'd') != NULL);
  127.     int try_unix = (vim_strchr(p_ffs, 'x') != NULL);
  128. #ifdef AUTOCMD
  129.     write_no_eol_lnum = 0; /* in case it was set by the previous read */
  130. #endif
  131.     /*
  132.      * If there is no file name yet, use the one for the read file.
  133.      * b_notedited is set to reflect this.
  134.      * Don't do this for a read from a filter.
  135.      * Only do this when 'cpoptions' contains the 'f' flag.
  136.      */
  137.     if (curbuf->b_ffname == NULL && !filtering && !read_stdin &&
  138. vim_strchr(p_cpo, CPO_FNAMER) != NULL)
  139.     {
  140. if (setfname(fname, sfname, FALSE) == OK)
  141.     curbuf->b_notedited = TRUE;
  142.     }
  143.     if (shortmess(SHM_OVER) || curbuf->b_help)
  144. msg_scroll = FALSE; /* overwrite previous file message */
  145.     else
  146. msg_scroll = TRUE; /* don't overwrite previous file message */
  147.     if (sfname == NULL)
  148. sfname = fname;
  149.     /*
  150.      * For Unix: Use the short file name whenever possible.
  151.      * Avoids problems with networks and when directory names are changed.
  152.      * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to
  153.      * another directory, which we don't detect.
  154.      */
  155. #if defined(UNIX) || defined(__EMX__)
  156.     fname = sfname;
  157. #endif
  158.     /* set default 'fileformat' */
  159.     if (newfile && *p_ffs)
  160. set_fileformat(default_fileformat());
  161. #ifdef UNIX
  162.     /*
  163.      * On Unix it is possible to read a directory, so we have to
  164.      * check for it before the open().
  165.      */
  166.     if (!read_stdin)
  167.     {
  168. perm = mch_getperm(fname);
  169. if (perm >= 0 && !S_ISREG(perm)     /* not a regular file ... */
  170. # ifdef S_ISFIFO
  171.       && !S_ISFIFO(perm)     /* ... or fifo */
  172. # endif
  173. # ifdef S_ISSOCK
  174.       && !S_ISSOCK(perm)     /* ... or socket */
  175. # endif
  176. )
  177. {
  178.     if (S_ISDIR(perm))
  179. filemess(curbuf, fname, (char_u *)"is a directory", 0);
  180.     else
  181. filemess(curbuf, fname, (char_u *)"is not a file", 0);
  182.     msg_end();
  183.     msg_scroll = msg_save;
  184.     return FAIL;
  185. }
  186.     }
  187. #endif
  188.     /*
  189.      * When opening a new file we take the readonly flag from the file.
  190.      * Default is r/w, can be set to r/o below.
  191.      * Don't reset it when in readonly mode
  192.      * Only set/reset b_p_ro when BF_CHECK_RO is set.
  193.      */
  194.     check_readonly = (newfile && (curbuf->b_flags & BF_CHECK_RO));
  195.     if (check_readonly && !readonlymode)    /* default: set file not readonly */
  196. curbuf->b_p_ro = FALSE;
  197.     if (newfile && !read_stdin)
  198.     {
  199. /* Remember time of file.
  200.  * For RISCOS, also remember the filetype.
  201.  */
  202. if (stat((char *)fname, &st) >= 0)
  203. {
  204.     curbuf->b_mtime = st.st_mtime;
  205.     curbuf->b_mtime_read = st.st_mtime;
  206. #if defined(RISCOS) && defined(WANT_FILETYPE)
  207.     /* Read the filetype into the buffer local filetype option. */
  208.     ro_read_filetype(fname);
  209. #endif
  210. #ifdef UNIX
  211.     /*
  212.      * Set the protection bits of the swap file equal to the original
  213.      * file. This makes it possible for others to read the name of the
  214.      * original file from the swapfile.
  215.      */
  216.     if (curbuf->b_ml.ml_mfp->mf_fname != NULL)
  217. (void)mch_setperm(curbuf->b_ml.ml_mfp->mf_fname,
  218.   (long)((st.st_mode & 0777) | 0600));
  219. #endif
  220. }
  221. else
  222. {
  223.     curbuf->b_mtime = 0;
  224.     curbuf->b_mtime_read = 0;
  225. }
  226.     }
  227. /*
  228.  * for UNIX: check readonly with perm and access()
  229.  * for RISCOS: same as Unix, otherwise file gets re-datestamped!
  230.  * for MSDOS and Amiga: check readonly by trying to open the file for writing
  231.  */
  232.     file_readonly = FALSE;
  233.     if (read_stdin)
  234. fd = 0;
  235.     else
  236.     {
  237. #if defined(UNIX) || defined(DJGPP) || defined(__EMX__) || defined(VMS) || defined(RISCOS)
  238. if (
  239. # ifdef UNIX
  240.     !(perm & 0222) ||
  241. # endif
  242. access((char *)fname, W_OK))
  243.     file_readonly = TRUE;
  244. fd = open((char *)fname, O_RDONLY | O_EXTRA
  245. #ifndef macintosh
  246.     , 0
  247. #endif
  248. );
  249. #else
  250. if (!newfile || readonlymode || (fd =
  251.    open((char *)fname, O_RDWR | O_EXTRA
  252. #ifndef macintosh
  253.    , 0     /* mode (avoid UMR) */
  254. #endif
  255.    )) < 0)
  256. {
  257.     file_readonly = TRUE;
  258.     fd = open((char *)fname, O_RDONLY | O_EXTRA
  259. #ifndef macintosh
  260.    , 0     /* mode (avoid UMR) */
  261. #endif
  262.     );   /* try to open ro */
  263. }
  264. #endif
  265.     }
  266.     if (fd < 0)     /* cannot open at all */
  267.     {
  268. #ifndef UNIX
  269. int isdir_f;
  270. #endif
  271. msg_scroll = msg_save;
  272. #ifndef UNIX
  273.     /*
  274.      * On MSDOS and Amiga we can't open a directory, check here.
  275.      */
  276. isdir_f = (mch_isdir(fname));
  277. perm = mch_getperm(fname);  /* check if the file exists */
  278. fname = sfname;     /* use short name now, for the messages */
  279. if (isdir_f)
  280.     filemess(curbuf, fname, (char_u *)"is a directory", 0);
  281. else
  282. #endif
  283.     if (newfile)
  284.     {
  285. if (perm < 0)
  286. {
  287.     check_need_swap(newfile); /* may create swap file now */
  288.     filemess(curbuf, fname, (char_u *)"[New File]", 0);
  289. #ifdef AUTOCMD
  290.     apply_autocmds(EVENT_BUFNEWFILE, fname, fname, FALSE,
  291.       curbuf);
  292. #endif
  293.     /* remember the current file format */
  294.     curbuf->b_start_ffc = *curbuf->b_p_ff;
  295.     return OK;     /* a new file is not an error */
  296. }
  297. else
  298.     filemess(curbuf, fname, (char_u *)"[Permission Denied]", 0);
  299.     }
  300. return FAIL;
  301.     }
  302.     /*
  303.      * Only set the 'ro' flag for readonly files the first time they are
  304.      * loaded. Help files always get readonly mode
  305.      */
  306.     if ((check_readonly && file_readonly) || curbuf->b_help)
  307. curbuf->b_p_ro = TRUE;
  308.     if (newfile)
  309. curbuf->b_p_eol = TRUE;
  310.     check_need_swap(newfile); /* may create swap file now */
  311. #ifndef UNIX
  312.     fname = sfname;     /* replace with short name now, for the messages */
  313. #endif
  314.     ++no_wait_return;     /* don't wait for return yet */
  315.     /*
  316.      * Set '[ mark to the line above where the lines go (line 1 if zero).
  317.      */
  318.     curbuf->b_op_start.lnum = ((from == 0) ? 1 : from);
  319.     curbuf->b_op_start.col = 0;
  320. #ifdef AUTOCMD
  321.     {
  322. int m = msg_scroll;
  323. int n = msg_scrolled;
  324. BUF *old_curbuf = curbuf;
  325. /*
  326.  * The file must be closed again, the autocommands may want to change
  327.  * the file before reading it.
  328.  */
  329. if (!read_stdin)
  330.     close(fd); /* ignore errors */
  331. /*
  332.  * The output from the autocommands should not overwrite anything and
  333.  * should not be overwritten: Set msg_scroll, restore its value if no
  334.  * output was done.
  335.  */
  336. msg_scroll = TRUE;
  337. if (filtering)
  338.     apply_autocmds(EVENT_FILTERREADPRE, NULL, fname, FALSE, curbuf);
  339. else if (read_stdin)
  340.     apply_autocmds(EVENT_STDINREADPRE, NULL, fname, FALSE, curbuf);
  341. else if (newfile)
  342.     apply_autocmds(EVENT_BUFREADPRE, NULL, fname, FALSE, curbuf);
  343. else
  344.     apply_autocmds(EVENT_FILEREADPRE, fname, fname, FALSE, NULL);
  345. if (msg_scrolled == n)
  346.     msg_scroll = m;
  347. /*
  348.  * Don't allow the autocommands to change the current buffer.
  349.  * Try to re-open the file.
  350.  */
  351. if (!read_stdin && (curbuf != old_curbuf ||
  352.   (fd = open((char *)fname, O_RDONLY | O_EXTRA
  353. #ifndef macintosh
  354.    , 0     /* mode (avoid UMR) */
  355. #endif
  356.      )) < 0))
  357. {
  358.     --no_wait_return;
  359.     msg_scroll = msg_save;
  360.     if (fd < 0)
  361. EMSG("*ReadPre autocommands made the file unreadable");
  362.     else
  363. EMSG("*ReadPre autocommands must not change current buffer");
  364.     return FAIL;
  365. }
  366.     }
  367. #endif
  368.     /* Autocommands may add lines to the file, need to check if it is empty */
  369.     wasempty = (curbuf->b_ml.ml_flags & ML_EMPTY);
  370.     if (!recoverymode && !filtering && !read_stdin)
  371. filemess(curbuf, fname, (char_u *)"", 0);   /* show that we are busy */
  372.     msg_scroll = FALSE; /* overwrite the file message */
  373.     /*
  374.      * Set fileformat and linecnt now, before the "retry" caused by a wrong
  375.      * guess for fileformat, and after the autocommands, which may change
  376.      * them.
  377.      */
  378.     if (curbuf->b_p_bin)
  379. fileformat = EOL_UNIX;     /* binary: use Unix format */
  380.     else if (*p_ffs == NUL)
  381. fileformat = get_fileformat(curbuf);  /* use format from buffer */
  382.     else
  383. fileformat = EOL_UNKNOWN;     /* detect from file */
  384.     linecnt = curbuf->b_ml.ml_line_count;
  385. retry:
  386.     linerest = 0;
  387.     filesize = 0;
  388.     skip_count = lines_to_skip;
  389.     read_count = lines_to_read;
  390.     while (!error && !got_int)
  391.     {
  392. /*
  393.  * We allocate as much space for the file as we can get, plus
  394.  * space for the old line plus room for one terminating NUL.
  395.  * The amount is limited by the fact that read() only can read
  396.  * upto max_unsigned characters (and other things).
  397.  */
  398. #if SIZEOF_INT <= 2
  399. if (linerest >= 0x7ff0)
  400. {
  401.     ++split;
  402.     *ptr = NL;     /* split line by inserting a NL */
  403.     size = 1;
  404. }
  405. else
  406. #endif
  407. {
  408. #if SIZEOF_INT > 2
  409.     size = 0x10000L;     /* use buffer >= 64K */
  410. #else
  411.     size = 0x7ff0L - linerest;     /* limit buffer to 32K */
  412. #endif
  413.     for ( ; size >= 10; size = (long_u)size >> 1)
  414.     {
  415. if ((new_buffer = lalloc((long_u)(size + linerest + 1),
  416.       FALSE)) != NULL)
  417.     break;
  418.     }
  419.     if (new_buffer == NULL)
  420.     {
  421. do_outofmem_msg();
  422. error = TRUE;
  423. break;
  424.     }
  425.     if (linerest) /* copy characters from the previous buffer */
  426. mch_memmove(new_buffer, ptr - linerest, (size_t)linerest);
  427.     vim_free(buffer);
  428.     buffer = new_buffer;
  429.     ptr = buffer + linerest;
  430.     line_start = buffer;
  431.     if ((size = read(fd, (char *)ptr, (size_t)size)) <= 0)
  432.     {
  433. if (size < 0)     /* read error */
  434.     error = TRUE;
  435. break;
  436.     }
  437.     filesize += size;     /* count the number of characters */
  438.     /*
  439.      * when reading the first part of a file: guess EOL type
  440.      */
  441.     if (fileformat == EOL_UNKNOWN)
  442.     {
  443. /* First try finding a NL, for Dos and Unix */
  444. if (try_dos || try_unix)
  445. {
  446.     for (p = ptr; p < ptr + size; ++p)
  447. if (*p == NL)
  448. {
  449.     if (!try_unix
  450.     || (try_dos && p > ptr && p[-1] == CR))
  451. fileformat = EOL_DOS;
  452.     else
  453. fileformat = EOL_UNIX;
  454.     break;
  455. }
  456. }
  457. /* No NL found: may use Mac format */
  458. if (fileformat == EOL_UNKNOWN && try_mac)
  459.     fileformat = EOL_MAC;
  460. /* Still nothing found?  Use first format in 'ffs' */
  461. if (fileformat == EOL_UNKNOWN)
  462.     fileformat = default_fileformat();
  463. /* if editing a new file: may set p_tx and p_ff */
  464. if (newfile)
  465.     set_fileformat(fileformat);
  466.     }
  467. }
  468. /*
  469.  * This loop is executed once for every character read.
  470.  * Keep it fast!
  471.  */
  472. if (fileformat == EOL_MAC)
  473. {
  474.     --ptr;
  475.     while (++ptr, --size >= 0)
  476.     {
  477. /* catch most common case first */
  478. if ((c = *ptr) != NUL && c != CR && c != NL)
  479.     continue;
  480. if (c == NUL)
  481.     *ptr = NL; /* NULs are replaced by newlines! */
  482. else
  483. {
  484.     if (skip_count == 0)
  485.     {
  486. if (c == NL)
  487. {
  488.     /*
  489.      * Reading in Mac format, but a NL found!
  490.      * When 'fileformats' includes "unix" or "dos",
  491.      * delete all the lines read so far and start all
  492.      * over again.  Otherwise give an error message
  493.      * later.
  494.      */
  495.     if (ff_error == EOL_UNKNOWN)
  496.     {
  497. if ((try_dos || try_unix)
  498. && !read_stdin
  499. && lseek(fd, (off_t)0L, SEEK_SET) == 0)
  500. {
  501.     while (lnum > from)
  502. ml_delete(lnum--, FALSE);
  503.     if (!try_unix || ptr[-1] == NUL)
  504. fileformat = EOL_DOS;
  505.     else
  506. fileformat = EOL_UNIX;
  507.     if (newfile)
  508. set_fileformat(fileformat);
  509.     goto retry;
  510. }
  511. else
  512.     ff_error = EOL_MAC;
  513.     }
  514. }
  515. *ptr = NUL;     /* end of line */
  516. len = ptr - line_start + 1;
  517. if (ml_append(lnum, line_start, len, newfile) == FAIL)
  518. {
  519.     error = TRUE;
  520.     break;
  521. }
  522. ++lnum;
  523. if (--read_count == 0)
  524. {
  525.     error = TRUE;     /* break loop */
  526.     line_start = ptr; /* nothing left to write */
  527.     break;
  528. }
  529.     }
  530.     else
  531. --skip_count;
  532.     line_start = ptr + 1;
  533. }
  534.     }
  535. }
  536. else
  537. {
  538.     --ptr;
  539.     while (++ptr, --size >= 0)
  540.     {
  541. if ((c = *ptr) != NUL && c != NL)  /* catch most common case */
  542.     continue;
  543. if (c == NUL)
  544.     *ptr = NL; /* NULs are replaced by newlines! */
  545. else
  546. {
  547.     if (skip_count == 0)
  548.     {
  549. *ptr = NUL; /* end of line */
  550. len = ptr - line_start + 1;
  551. if (fileformat == EOL_DOS)
  552. {
  553.     if (ptr[-1] == CR) /* remove CR */
  554.     {
  555. ptr[-1] = NUL;
  556. --len;
  557.     }
  558.     /*
  559.      * Reading in Dos format, but no CR-LF found!
  560.      * When 'fileformats' includes "unix", delete all
  561.      * the lines read so far and start all over again.
  562.      * Otherwise give an error message later.
  563.      */
  564.     else if (ff_error != EOL_DOS)
  565.     {
  566. if (    try_unix
  567. && !read_stdin
  568. && lseek(fd, (off_t)0L, SEEK_SET) == 0)
  569. {
  570.     while (lnum > from)
  571. ml_delete(lnum--, FALSE);
  572.     fileformat = EOL_UNIX;
  573.     if (newfile)
  574. set_fileformat(EOL_UNIX);
  575.     goto retry;
  576. }
  577. else
  578.     ff_error = EOL_DOS;
  579.     }
  580. }
  581. if (ml_append(lnum, line_start, len, newfile) == FAIL)
  582. {
  583.     error = TRUE;
  584.     break;
  585. }
  586. ++lnum;
  587. if (--read_count == 0)
  588. {
  589.     error = TRUE;     /* break loop */
  590.     line_start = ptr; /* nothing left to write */
  591.     break;
  592. }
  593.     }
  594.     else
  595. --skip_count;
  596.     line_start = ptr + 1;
  597. }
  598.     }
  599. }
  600. linerest = ptr - line_start;
  601. ui_breakcheck();
  602.     }
  603.     /* not an error, max. number of lines reached */
  604.     if (error && read_count == 0)
  605. error = FALSE;
  606.     /*
  607.      * If we get EOF in the middle of a line, note the fact and
  608.      * complete the line ourselves.
  609.      * In Dos format ignore a trailing CTRL-Z, unless 'binary' set.
  610.      */
  611.     if (!error && !got_int && linerest != 0 &&
  612.     !(!curbuf->b_p_bin && fileformat == EOL_DOS &&
  613.     *line_start == Ctrl('Z') && ptr == line_start + 1))
  614.     {
  615. if (newfile)     /* remember for when writing */
  616.     curbuf->b_p_eol = FALSE;
  617. *ptr = NUL;
  618. if (ml_append(lnum, line_start,
  619. (colnr_t)(ptr - line_start + 1), newfile) == FAIL)
  620.     error = TRUE;
  621. else
  622.     read_no_eol_lnum = ++lnum;
  623.     }
  624.     if (lnum != from && !newfile)   /* added at least one line */
  625. changed();
  626.     invalidate_botline();     /* need to recompute w_botline */
  627.     changed_line_abv_curs();     /* need to recompute cursor posn */
  628.     if (newfile)
  629. curbuf->b_start_ffc = *curbuf->b_p_ff; /* remember 'fileformat' */
  630.     close(fd);     /* errors are ignored */
  631.     vim_free(buffer);
  632.     --no_wait_return;     /* may wait for return now */
  633.     /*
  634.      * In recovery mode everything but autocommands are skipped.
  635.      */
  636.     if (!recoverymode)
  637.     {
  638. /* need to delete the last line, which comes from the empty buffer */
  639. if (newfile && wasempty && !(curbuf->b_ml.ml_flags & ML_EMPTY))
  640. {
  641.     ml_delete(curbuf->b_ml.ml_line_count, FALSE);
  642.     --linecnt;
  643. }
  644. linecnt = curbuf->b_ml.ml_line_count - linecnt;
  645. if (filesize == 0)
  646.     linecnt = 0;
  647. if (!newfile)
  648.     mark_adjust(from + 1, (linenr_t)MAXLNUM, (long)linecnt, 0L);
  649. /*
  650.  * If we were reading from the same terminal as where messages go,
  651.  * the screen will have been messed up.
  652.  * Switch on raw mode now and clear the screen.
  653.  */
  654. if (read_stdin)
  655. {
  656.     settmode(TMODE_RAW);     /* set to raw mode */
  657.     starttermcap();
  658.     screenclear();
  659. }
  660. if (got_int)
  661. {
  662.     filemess(curbuf, fname, e_interr, 0);
  663.     msg_scroll = msg_save;
  664. #ifdef VIMINFO
  665.     check_marks_read();
  666. #endif
  667.     return OK; /* an interrupt isn't really an error */
  668. }
  669. if (!filtering)
  670. {
  671.     msg_add_fname(curbuf, fname);   /* fname in IObuff with quotes */
  672.     c = FALSE;
  673. #ifdef UNIX
  674. # ifdef S_ISFIFO
  675.     if (S_ISFIFO(perm))     /* fifo or socket */
  676.     {
  677. STRCAT(IObuff, "[fifo/socket]");
  678. c = TRUE;
  679.     }
  680. # else
  681. #  ifdef S_IFIFO
  682.     if ((perm & S_IFMT) == S_IFIFO)     /* fifo */
  683.     {
  684. STRCAT(IObuff, "[fifo]");
  685. c = TRUE;
  686.     }
  687. #  endif
  688. #  ifdef S_IFSOCK
  689.     if ((perm & S_IFMT) == S_IFSOCK)     /* or socket */
  690.     {
  691. STRCAT(IObuff, "[socket]");
  692. c = TRUE;
  693.     }
  694. #  endif
  695. # endif
  696. #endif
  697.     if (curbuf->b_p_ro)
  698.     {
  699. STRCAT(IObuff, shortmess(SHM_RO) ? "[RO]" : "[readonly]");
  700. c = TRUE;
  701.     }
  702.     if (read_no_eol_lnum)
  703.     {
  704. msg_add_eol();
  705. c = TRUE;
  706.     }
  707.     if (ff_error == EOL_DOS)
  708.     {
  709. STRCAT(IObuff, "[CR missing]");
  710. c = TRUE;
  711.     }
  712.     if (ff_error == EOL_MAC)
  713.     {
  714. STRCAT(IObuff, "[NL found]");
  715. c = TRUE;
  716.     }
  717.     if (split)
  718.     {
  719. STRCAT(IObuff, "[long lines split]");
  720. c = TRUE;
  721.     }
  722.     if (error)
  723.     {
  724. STRCAT(IObuff, "[READ ERRORS]");
  725. c = TRUE;
  726.     }
  727.     if (msg_add_fileformat(fileformat))
  728. c = TRUE;
  729.     msg_add_lines(c, (long)linecnt, filesize);
  730.     msg_trunc_attr(IObuff, FALSE, 0);
  731. }
  732. if (error && newfile) /* with errors we should not write the file */
  733.     curbuf->b_p_ro = TRUE;
  734. u_clearline();     /* cannot use "U" command after adding lines */
  735. /*
  736.  * In Ex mode: cursor at last new line.
  737.  * Otherwise: cursor at first new line.
  738.  */
  739. if (exmode_active)
  740.     curwin->w_cursor.lnum = from + linecnt;
  741. else
  742.     curwin->w_cursor.lnum = from + 1;
  743. check_cursor_lnum();
  744. beginline(BL_WHITE | BL_FIX);     /* on first non-blank */
  745. /*
  746.  * Set '[ and '] marks to the newly read lines.
  747.  */
  748. curbuf->b_op_start.lnum = from + 1;
  749. curbuf->b_op_start.col = 0;
  750. curbuf->b_op_end.lnum = from + linecnt;
  751. curbuf->b_op_end.col = 0;
  752.     }
  753.     msg_scroll = msg_save;
  754. #ifdef VIMINFO
  755.     /*
  756.      * Get the marks before executing autocommands, so they can be used there.
  757.      */
  758.     check_marks_read();
  759. #endif
  760. #ifdef AUTOCMD
  761.     {
  762. int m = msg_scroll;
  763. int n = msg_scrolled;
  764. /*
  765.  * Trick: We remember if the last line of the read didn't have
  766.  * an eol for when writing it again.  This is required for
  767.  * ":autocmd FileReadPost *.gz set bin|'[,']!gunzip" to work.
  768.  */
  769. write_no_eol_lnum = read_no_eol_lnum;
  770. /*
  771.  * The output from the autocommands should not overwrite anything and
  772.  * should not be overwritten: Set msg_scroll, restore its value if no
  773.  * output was done.
  774.  */
  775. msg_scroll = TRUE;
  776. if (filtering)
  777.     apply_autocmds(EVENT_FILTERREADPOST, NULL, fname, FALSE, curbuf);
  778. else if (read_stdin)
  779.     apply_autocmds(EVENT_STDINREADPOST, NULL, fname, FALSE, curbuf);
  780. else if (newfile)
  781.     apply_autocmds(EVENT_BUFREADPOST, NULL, fname, FALSE, curbuf);
  782. else
  783.     apply_autocmds(EVENT_FILEREADPOST, fname, fname, FALSE, NULL);
  784. if (msg_scrolled == n)
  785.     msg_scroll = m;
  786.     }
  787. #endif
  788.     if (recoverymode && error)
  789. return FAIL;
  790.     return OK;
  791. }
  792. #ifdef VIMINFO
  793.     static void
  794. check_marks_read()
  795. {
  796.     if (!curbuf->b_marks_read && get_viminfo_parameter(''') > 0)
  797.     {
  798. read_viminfo(NULL, FALSE, TRUE, FALSE);
  799. curbuf->b_marks_read = TRUE;
  800.     }
  801. }
  802. #endif
  803. #ifdef UNIX
  804.     static void
  805. set_file_time(fname, atime, mtime)
  806.     char_u  *fname;
  807.     time_t  atime;     /* access time */
  808.     time_t  mtime;     /* modification time */
  809. {
  810. # if defined(HAVE_UTIME) && defined(HAVE_UTIME_H)
  811. #  include <utime.h>
  812.     struct utimbuf  buf;
  813.     buf.actime = atime;
  814.     buf.modtime = mtime;
  815.     (void)utime((char *)fname, &buf);
  816. # else
  817. #  if defined(HAVE_UTIMES)
  818.     struct timeval  tvp[2];
  819.     tvp[0].tv_sec   = atime;
  820.     tvp[0].tv_usec  = 0;
  821.     tvp[1].tv_sec   = mtime;
  822.     tvp[1].tv_usec  = 0;
  823. #   ifdef NeXT
  824.     (void)utimes((char *)fname, tvp);
  825. #   else
  826.     (void)utimes((char *)fname, &tvp);
  827. #   endif
  828. #  endif
  829. # endif
  830. }
  831. #endif /* UNIX */
  832. /*
  833.  * buf_write() - write to file 'fname' lines 'start' through 'end'
  834.  *
  835.  * We do our own buffering here because fwrite() is so slow.
  836.  *
  837.  * If forceit is true, we don't care for errors when attempting backups (jw).
  838.  * In case of an error everything possible is done to restore the original file.
  839.  * But when forceit is TRUE, we risk loosing it.
  840.  * When reset_changed is TRUE and start == 1 and end ==
  841.  * curbuf->b_ml.ml_line_count, reset curbuf->b_changed.
  842.  *
  843.  * This function must NOT use NameBuff (because it's called by autowrite()).
  844.  *
  845.  * return FAIL for failure, OK otherwise
  846.  */
  847.     int
  848. buf_write(buf, fname, sfname, start, end, append, forceit,
  849.       reset_changed, filtering)
  850.     BUF     *buf;
  851.     char_u     *fname;
  852.     char_u     *sfname;
  853.     linenr_t     start, end;
  854.     int     append;
  855.     int     forceit;
  856.     int     reset_changed;
  857.     int     filtering;
  858. {
  859.     int     fd;
  860.     char_u     *backup = NULL;
  861.     char_u     *ffname;
  862. #ifdef AUTOCMD
  863.     BUF     *save_buf;
  864. #endif
  865.     char_u     *s;
  866.     char_u     *ptr;
  867.     char_u     c;
  868.     int     len;
  869.     linenr_t     lnum;
  870.     long     nchars;
  871.     char_u     *errmsg = NULL;
  872.     char_u     *buffer;
  873.     char_u     smallbuf[SMBUFSIZE];
  874.     char_u     *backup_ext;
  875.     int     bufsize;
  876.     long     perm;     /* file permissions */
  877.     int     retval = OK;
  878.     int     newfile = FALSE;     /* TRUE if file doesn't exist yet */
  879.     int     msg_save = msg_scroll;
  880.     int     overwriting;     /* TRUE if writing over original */
  881.     int     no_eol = FALSE;     /* no end-of-line written */
  882. #if defined(UNIX) || defined(__EMX__XX)     /*XXX fix me sometime? */
  883.     struct stat     st_old;
  884.     int     made_writable = FALSE;  /* 'w' bit has been set */
  885. #endif
  886. #ifdef AMIGA
  887.     BPTR     flock;
  888. #endif
  889. #ifdef VMS
  890.     char_u     *cp, nfname[MAXPATHL];
  891. #endif
  892.     /* writing everything */
  893.     int     whole = (start == 1 && end == buf->b_ml.ml_line_count);
  894. #ifdef AUTOCMD
  895.     linenr_t     old_line_count = buf->b_ml.ml_line_count;
  896. #endif
  897.     int     attr;
  898.     int     fileformat = get_fileformat(buf);
  899.     if (fname == NULL || *fname == NUL)     /* safety check */
  900. return FAIL;
  901.     /*
  902.      * If there is no file name yet, use the one for the written file.
  903.      * b_notedited is set to reflect this (in case the write fails).
  904.      * Don't do this when the write is for a filter command.
  905.      * Only do this when 'cpoptions' contains the 'f' flag.
  906.      */
  907.     if (reset_changed && whole && buf == curbuf &&
  908.    curbuf->b_ffname == NULL && !filtering &&
  909. vim_strchr(p_cpo, CPO_FNAMEW) != NULL)
  910.     {
  911. if (setfname(fname, sfname, FALSE) == OK)
  912.     curbuf->b_notedited = TRUE;
  913.     }
  914.     if (sfname == NULL)
  915. sfname = fname;
  916.     /*
  917.      * For Unix: Use the short file name whenever possible.
  918.      * Avoids problems with networks and when directory names are changed.
  919.      * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to
  920.      * another directory, which we don't detect
  921.      */
  922.     ffname = fname;     /* remember full fname */
  923. #ifdef UNIX
  924.     fname = sfname;
  925. #endif
  926. /* make sure we have a valid backup extension to use */
  927.     if (*p_bex == NUL)
  928. #ifdef RISCOS
  929. backup_ext = (char_u *)"/bak";
  930. #else
  931. backup_ext = (char_u *)".bak";
  932. #endif
  933.     else
  934. backup_ext = p_bex;
  935.     if (buf->b_ffname != NULL && fnamecmp(ffname, buf->b_ffname) == 0)
  936. overwriting = TRUE;
  937.     else
  938. overwriting = FALSE;
  939.     /*
  940.      * Disallow writing from .exrc and .vimrc in current directory for
  941.      * security reasons.
  942.      */
  943.     if (check_secure())
  944. return FAIL;
  945.     if (exiting)
  946. settmode(TMODE_COOK);     /* when exiting allow typahead now */
  947.     ++no_wait_return;     /* don't wait for return yet */
  948.     /*
  949.      * Set '[ and '] marks to the lines to be written.
  950.      */
  951.     buf->b_op_start.lnum = start;
  952.     buf->b_op_start.col = 0;
  953.     buf->b_op_end.lnum = end;
  954.     buf->b_op_end.col = 0;
  955. #ifdef AUTOCMD
  956.     /*
  957.      * Apply PRE aucocommands.
  958.      * Set curbuf to the buffer to be written.
  959.      * Careful: The autocommands may call buf_write() recursively!
  960.      */
  961.     save_buf = curbuf;
  962.     curbuf = buf;
  963.     curwin->w_buffer = buf;
  964.     if (append)
  965. apply_autocmds(EVENT_FILEAPPENDPRE, fname, fname, FALSE, curbuf);
  966.     else if (filtering)
  967. apply_autocmds(EVENT_FILTERWRITEPRE, NULL, fname, FALSE, curbuf);
  968.     else if (reset_changed && whole)
  969. apply_autocmds(EVENT_BUFWRITEPRE, fname, fname, FALSE, curbuf);
  970.     else
  971. apply_autocmds(EVENT_FILEWRITEPRE, fname, fname, FALSE, curbuf);
  972.     /*
  973.      * If the autocommands deleted or unloaded the buffer, give an error
  974.      * message.
  975.      */
  976.     if (!buf_valid(buf) || buf->b_ml.ml_mfp == NULL)
  977.     {
  978. --no_wait_return;
  979. msg_scroll = msg_save;
  980. EMSG("Autocommands deleted or unloaded buffer to be written");
  981. return FAIL;
  982.     }
  983.     /*
  984.      * If the autocommands didn't change the current buffer, go back to the
  985.      * original current buffer, if it still exists.
  986.      */
  987.     if (curbuf == buf && buf_valid(save_buf))
  988.     {
  989. curbuf = save_buf;
  990. curwin->w_buffer = save_buf;
  991.     }
  992.     /*
  993.      * The autocommands may have changed the number of lines in the file.
  994.      * When writing the whole file, adjust the end.
  995.      * When writing part of the file, assume that the autocommands only
  996.      * changed the number of lines that are to be written (tricky!).
  997.      */
  998.     if (buf->b_ml.ml_line_count != old_line_count)
  999.     {
  1000. if (whole)     /* writing all */
  1001.     end = buf->b_ml.ml_line_count;
  1002. else if (buf->b_ml.ml_line_count > old_line_count)  /* more lines */
  1003.     end += buf->b_ml.ml_line_count - old_line_count;
  1004. else     /* less lines */
  1005. {
  1006.     end -= old_line_count - buf->b_ml.ml_line_count;
  1007.     if (end < start)
  1008.     {
  1009. --no_wait_return;
  1010. msg_scroll = msg_save;
  1011. EMSG("Autocommand changed number of lines in unexpected way");
  1012. return FAIL;
  1013.     }
  1014. }
  1015.     }
  1016. #endif
  1017.     if (shortmess(SHM_OVER))
  1018. msg_scroll = FALSE;     /* overwrite previous file message */
  1019.     else
  1020. msg_scroll = TRUE;     /* don't overwrite previous file message */
  1021.     if (!filtering)
  1022. filemess(buf,
  1023. #ifndef UNIX
  1024. sfname,
  1025. #else
  1026. fname,
  1027. #endif
  1028.     (char_u *)"", 0); /* show that we are busy */
  1029.     msg_scroll = FALSE;     /* always overwrite the file message now */
  1030.     buffer = alloc(BUFSIZE);
  1031.     if (buffer == NULL)     /* can't allocate big buffer, use small
  1032.      * one (to be able to write when out of
  1033.      * memory) */
  1034.     {
  1035. buffer = smallbuf;
  1036. bufsize = SMBUFSIZE;
  1037.     }
  1038.     else
  1039. bufsize = BUFSIZE;
  1040. #if defined(UNIX) && !defined(ARCHIE)
  1041. /* get information about original file (if there is one) */
  1042.     st_old.st_dev = st_old.st_ino = 0;
  1043.     perm = -1;
  1044.     if (stat((char *)fname, &st_old))
  1045. newfile = TRUE;
  1046.     else
  1047.     {
  1048. if (!S_ISREG(st_old.st_mode)) /* not a file */
  1049. {
  1050.     if (S_ISDIR(st_old.st_mode))
  1051. errmsg = (char_u *)"is a directory";
  1052.     else
  1053. errmsg = (char_u *)"is not a file";
  1054.     goto fail;
  1055. }
  1056. if (overwriting)
  1057. {
  1058.     retval = check_mtime(buf, &st_old);
  1059.     if (retval == FAIL)
  1060. goto fail;
  1061. }
  1062. perm = st_old.st_mode;
  1063.     }
  1064. /*
  1065.  * If we are not appending or filtering, the file exists, and the
  1066.  * 'writebackup', 'backup' or 'patchmode' option is set, try to make a backup
  1067.  * copy of the file.
  1068.  */
  1069.     if (!append && !filtering && perm >= 0 && (p_wb || p_bk || *p_pm != NUL)
  1070.     && (fd = open((char *)fname, O_RDONLY | O_EXTRA
  1071. #ifndef macintosh
  1072.    , 0     /* mode (avoid UMR) */
  1073. #endif
  1074. )) >= 0)
  1075.     {
  1076. int bfd, buflen;
  1077. char_u copybuf[BUFSIZE + 1], *wp;
  1078. int some_error = FALSE;
  1079. struct stat st_new;
  1080. char_u *dirp;
  1081. char_u *rootname;
  1082. #ifndef SHORT_FNAME
  1083. int did_set_shortname;
  1084. #endif
  1085. /*
  1086.  * Try to make the backup in each directory in the 'bdir' option.
  1087.  *
  1088.  * Unix semantics has it, that we may have a writable file,
  1089.  * that cannot be recreated with a simple open(..., O_CREAT, ) e.g:
  1090.  *  - the directory is not writable,
  1091.  *  - the file may be a symbolic link,
  1092.  *  - the file may belong to another user/group, etc.
  1093.  *
  1094.  * For these reasons, the existing writable file must be truncated
  1095.  * and reused. Creation of a backup COPY will be attempted.
  1096.  */
  1097. dirp = p_bdir;
  1098. while (*dirp)
  1099. {
  1100.     st_new.st_dev = st_new.st_ino = 0;
  1101.     st_new.st_gid = 0;
  1102.     /*
  1103.      * Isolate one directory name, using an entry in 'bdir'.
  1104.      */
  1105.     (void)copy_option_part(&dirp, copybuf, BUFSIZE, ",");
  1106.     rootname = get_file_in_dir(fname, copybuf);
  1107.     if (rootname == NULL)
  1108.     {
  1109. some_error = TRUE;     /* out of memory */
  1110. goto nobackup;
  1111.     }
  1112. #ifndef SHORT_FNAME
  1113.     did_set_shortname = FALSE;
  1114. #endif
  1115.     /*
  1116.      * May try twice if 'shortname' not set.
  1117.      */
  1118.     for (;;)
  1119.     {
  1120. /*
  1121.  * Make backup file name.
  1122.  */
  1123. backup = buf_modname(
  1124. #ifdef SHORT_FNAME
  1125. TRUE,
  1126. #else
  1127. (buf->b_p_sn || buf->b_shortname),
  1128. #endif
  1129.  rootname, backup_ext, FALSE);
  1130. if (backup == NULL)
  1131. {
  1132.     some_error = TRUE; /* out of memory */
  1133.     vim_free(rootname);
  1134.     goto nobackup;
  1135. }
  1136. /*
  1137.  * Check if backup file already exists.
  1138.  */
  1139. if (!stat((char *)backup, &st_new))
  1140. {
  1141.     /*
  1142.      * Check if backup file is same as original file.
  1143.      * May happen when modname gave the same file back.
  1144.      * E.g. silly link, or file name-length reached.
  1145.      * If we don't check here, we either ruin the file when
  1146.      * copying or erase it after writing. jw.
  1147.      */
  1148.     if (st_new.st_dev == st_old.st_dev &&
  1149.    st_new.st_ino == st_old.st_ino)
  1150.     {
  1151. vim_free(backup);
  1152. backup = NULL; /* there is no backup file to delete */
  1153. #ifndef SHORT_FNAME
  1154. /*
  1155.  * may try again with 'shortname' set
  1156.  */
  1157. if (!(buf->b_shortname || buf->b_p_sn))
  1158. {
  1159.     buf->b_shortname = TRUE;
  1160.     did_set_shortname = TRUE;
  1161.     continue;
  1162. }
  1163.     /* setting shortname didn't help */
  1164. if (did_set_shortname)
  1165.     buf->b_shortname = FALSE;
  1166. #endif
  1167. break;
  1168.     }
  1169.     /*
  1170.      * If we are not going to keep the backup file, don't
  1171.      * delete an existing one, try to use another name.
  1172.      * Change one character, just before the extension.
  1173.      */
  1174.     if (!p_bk)
  1175.     {
  1176. wp = backup + STRLEN(backup) - 1 - STRLEN(backup_ext);
  1177. if (wp < backup) /* empty file name ??? */
  1178.     wp = backup;
  1179. *wp = 'z';
  1180. while (*wp > 'a' && !stat((char *)backup, &st_new))
  1181.     --*wp;
  1182. /* They all exist??? Must be something wrong. */
  1183. if (*wp == 'a')
  1184. {
  1185.     vim_free(backup);
  1186.     backup = NULL;
  1187. }
  1188.     }
  1189. }
  1190. break;
  1191.     }
  1192.     vim_free(rootname);
  1193.     /*
  1194.      * Try to create the backup file
  1195.      */
  1196.     if (backup != NULL)
  1197.     {
  1198. /* remove old backup, if present */
  1199. mch_remove(backup);
  1200. bfd = open((char *)backup, O_WRONLY | O_CREAT | O_EXTRA, 0666);
  1201. if (bfd < 0)
  1202. {
  1203.     vim_free(backup);
  1204.     backup = NULL;
  1205. }
  1206. else
  1207. {
  1208.     /* set file protection same as original file, but strip
  1209.      * s-bit */
  1210.     (void)mch_setperm(backup, perm & 0777);
  1211.     /*
  1212.      * Try to set the group of the backup same as the original
  1213.      * file. If this fails, set the protection bits for the
  1214.      * group same as the protection bits for others.
  1215.      */
  1216.     if (st_new.st_gid != st_old.st_gid &&
  1217. #ifdef HAVE_FCHOWN  /* sequent-ptx lacks fchown() */
  1218.     fchown(bfd, (uid_t)-1, st_old.st_gid) != 0
  1219. #else
  1220.   chown((char *)backup, (uid_t)-1, st_old.st_gid) != 0
  1221. #endif
  1222.     )
  1223. mch_setperm(backup, (perm & 0707) | ((perm & 07) << 3));
  1224.     /* copy the file. */
  1225.     while ((buflen = read(fd, (char *)copybuf, BUFSIZE)) > 0)
  1226.     {
  1227. if (write_buf(bfd, copybuf, buflen) == FAIL)
  1228. {
  1229.     errmsg = (char_u *)"Can't write to backup file (use ! to override)";
  1230.     break;
  1231. }
  1232.     }
  1233.     if (close(bfd) < 0 && errmsg == NULL)
  1234. errmsg = (char_u *)"Close error for backup file (use ! to override)";
  1235.     if (buflen < 0)
  1236. errmsg = (char_u *)"Can't read file for backup (use ! to override)";
  1237.     set_file_time(backup, st_old.st_atime, st_old.st_mtime);
  1238.     break;
  1239. }
  1240.     }
  1241. }
  1242. nobackup:
  1243. close(fd); /* ignore errors for closing read file */
  1244. if (backup == NULL && errmsg == NULL)
  1245.     errmsg = (char_u *)"Cannot create backup file (use ! to override)";
  1246. /* ignore errors when forceit is TRUE */
  1247. if ((some_error || errmsg) && !forceit)
  1248. {
  1249.     retval = FAIL;
  1250.     goto fail;
  1251. }
  1252. errmsg = NULL;
  1253.     }
  1254.     /* When using ":w!" and the file was read-only: make it writable */
  1255.     if (forceit && st_old.st_uid == getuid() && perm >= 0 && !(perm & 0200)
  1256.      && vim_strchr(p_cpo, CPO_FWRITE) == NULL)
  1257.     {
  1258. perm |= 0200;
  1259. (void)mch_setperm(fname, perm);
  1260. made_writable = TRUE;
  1261.     }
  1262. #else /* end of UNIX, start of the rest */
  1263. /*
  1264.  * If we are not appending, the file exists, and the 'writebackup' or
  1265.  * 'backup' option is set, make a backup.
  1266.  * Do not make any backup, if "writebackup" and "backup" are
  1267.  * both switched off. This helps when editing large files on
  1268.  * almost-full disks. (jw)
  1269.  */
  1270.     perm = mch_getperm(fname);
  1271.     if (perm < 0)
  1272. newfile = TRUE;
  1273.     else if (mch_isdir(fname))
  1274.     {
  1275. errmsg = (char_u *)"is a directory";
  1276. goto fail;
  1277.     }
  1278.     else if (overwriting)
  1279.     {
  1280. struct stat st;
  1281. if (stat((char *)fname, &st) >= 0)
  1282. {
  1283.     retval = check_mtime(buf, &st);
  1284.     if (retval == FAIL)
  1285. goto fail;
  1286. }
  1287.     }
  1288.     if (!append && !filtering && perm >= 0 && (p_wb || p_bk || *p_pm != NUL))
  1289.     {
  1290. char_u *dirp;
  1291. char_u *p;
  1292. char_u *rootname;
  1293. /*
  1294.  * Form the backup file name - change path/fo.o.h to path/fo.o.h.bak
  1295.  * Try all directories in 'backupdir', first one that works is used.
  1296.  */
  1297. dirp = p_bdir;
  1298. while (*dirp)
  1299. {
  1300.     /*
  1301.      * Isolate one directory name and make the backup file name.
  1302.      */
  1303.     (void)copy_option_part(&dirp, IObuff, IOSIZE, ",");
  1304.     rootname = get_file_in_dir(fname, IObuff);
  1305.     if (rootname == NULL)
  1306. backup = NULL;
  1307.     else
  1308.     {
  1309. backup = buf_modname(
  1310. #ifdef SHORT_FNAME
  1311. TRUE,
  1312. #else
  1313. (buf->b_p_sn || buf->b_shortname),
  1314. #endif
  1315.  rootname, backup_ext, FALSE);
  1316. vim_free(rootname);
  1317.     }
  1318.     if (backup != NULL)
  1319.     {
  1320. /*
  1321.  * If we are not going to keep the backup file, don't
  1322.  * delete an existing one, try to use another name.
  1323.  * Change one character, just before the extension.
  1324.  */
  1325. if (!p_bk && mch_getperm(backup) >= 0)
  1326. {
  1327.     p = backup + STRLEN(backup) - 1 - STRLEN(backup_ext);
  1328.     if (p < backup) /* empty file name ??? */
  1329. p = backup;
  1330.     *p = 'z';
  1331.     while (*p > 'a' && mch_getperm(backup) >= 0)
  1332. --*p;
  1333.     /* They all exist??? Must be something wrong! */
  1334.     if (*p == 'a')
  1335.     {
  1336. vim_free(backup);
  1337. backup = NULL;
  1338.     }
  1339. }
  1340.     }
  1341.     if (backup != NULL)
  1342.     {
  1343. /*
  1344.  * Delete any existing backup and move the current version to
  1345.  * the backup. For safety, we don't remove the backup until
  1346.  * the write has finished successfully. And if the 'backup'
  1347.  * option is set, leave it around.
  1348.  */
  1349. #ifdef AMIGA
  1350. /*
  1351.  * With MSDOS-compatible filesystems (crossdos, messydos) it is
  1352.  * possible that the name of the backup file is the same as the
  1353.  * original file. To avoid the chance of accidently deleting the
  1354.  * original file (horror!) we lock it during the remove.
  1355.  * This should not happen with ":w", because startscript()
  1356.  * should detect this problem and set buf->b_shortname,
  1357.  * causing modname to return a correct ".bak" file name. This
  1358.  * problem does exist with ":w file name", but then the
  1359.  * original file will be somewhere else so the backup isn't
  1360.  * really important. If autoscripting is off the rename may
  1361.  * fail.
  1362.  */
  1363. flock = Lock((UBYTE *)fname, (long)ACCESS_READ);
  1364. #endif
  1365. mch_remove(backup);
  1366. #ifdef AMIGA
  1367. if (flock)
  1368.     UnLock(flock);
  1369. #endif
  1370. /*
  1371.  * If the renaming of the original file to the backup file
  1372.  * works, quit here.
  1373.  */
  1374. if (vim_rename(fname, backup) == 0)
  1375.     break;
  1376. vim_free(backup);   /* don't do the rename below */
  1377. backup = NULL;
  1378.     }
  1379. }
  1380. if (backup == NULL && !forceit)
  1381. {
  1382.     errmsg = (char_u *)"Can't make backup file (use ! to override)";
  1383.     goto fail;
  1384. }
  1385.     }
  1386. #endif /* UNIX */
  1387.     /* When using ":w!" and writing to the current file, readonly makes no
  1388.      * sense, reset it */
  1389.     if (forceit && overwriting)
  1390. buf->b_p_ro = FALSE;
  1391.     /*
  1392.      * If the original file is being overwritten, there is a small chance that
  1393.      * we crash in the middle of writing. Therefore the file is preserved now.
  1394.      * This makes all block numbers positive so that recovery does not need
  1395.      * the original file.
  1396.      * Don't do this if there is a backup file and we are exiting.
  1397.      */
  1398.     if (reset_changed && !newfile && !otherfile(ffname) &&
  1399.     !(exiting && backup != NULL))
  1400. ml_preserve(buf, FALSE);
  1401.     /*
  1402.      * We may try to open the file twice: If we can't write to the
  1403.      * file and forceit is TRUE we delete the existing file and try to create
  1404.      * a new one. If this still fails we may have lost the original file!
  1405.      * (this may happen when the user reached his quotum for number of files).
  1406.      * Appending will fail if the file does not exist and forceit is FALSE.
  1407.      */
  1408. #ifdef VMS
  1409.     STRCPY(nfname, fname);
  1410.     if (cp = vim_strchr(nfname, ';')) /* remove version */
  1411. *cp = '';
  1412. #endif
  1413.     while ((fd = open((char *)
  1414. #ifdef VMS
  1415.     nfname,
  1416. #else
  1417.     fname,
  1418. #endif
  1419.   O_WRONLY | O_EXTRA | (append ?
  1420.     (forceit ? (O_APPEND | O_CREAT) : O_APPEND) :
  1421.     (O_CREAT | O_TRUNC))
  1422. #ifndef macintosh
  1423. , 0666
  1424. #endif
  1425. )) < 0)
  1426.     {
  1427. /*
  1428.  * A forced write will try to create a new file if the old one is
  1429.  * still readonly. This may also happen when the directory is
  1430.  * read-only. In that case the mch_remove() will fail.
  1431.  */
  1432. if (!errmsg)
  1433. {
  1434.     errmsg = (char_u *)"Can't open file for writing";
  1435.     if (forceit && vim_strchr(p_cpo, CPO_FWRITE) == NULL)
  1436.     {
  1437. #ifdef UNIX
  1438. /* we write to the file, thus it should be marked
  1439.     writable after all */
  1440. if (!(perm & 0200))
  1441.     made_writable = TRUE;
  1442. perm |= 0200;
  1443. if (st_old.st_uid != getuid() || st_old.st_gid != getgid())
  1444.     perm &= 0777;
  1445. #endif
  1446. if (!append)     /* don't remove when appending */
  1447.     mch_remove(fname);
  1448. continue;
  1449.     }
  1450. }
  1451. /*
  1452.  * If we failed to open the file, we don't need a backup. Throw it away.
  1453.  * If we moved or removed the original file try to put the backup in its place.
  1454.  */
  1455. if (backup != NULL)
  1456. {
  1457. #ifdef UNIX
  1458.     struct stat st;
  1459.     /*
  1460.      * There is a small chance that we removed the original, try
  1461.      * to move the copy in its place.
  1462.      * This may not work if the vim_rename() fails.
  1463.      * In that case we leave the copy around.
  1464.      */
  1465. /* file does not exist */
  1466.     if (stat((char *)fname, &st) < 0)
  1467. /* put the copy in its place */
  1468. vim_rename(backup, fname);
  1469. /* original file does exist */
  1470.     if (stat((char *)fname, &st) >= 0)
  1471. mch_remove(backup); /* throw away the copy */
  1472. #else
  1473. /* try to put the original file back */
  1474.     vim_rename(backup, fname);
  1475. #endif
  1476. }
  1477. goto fail;
  1478.     }
  1479.     errmsg = NULL;
  1480.     if (end > buf->b_ml.ml_line_count)
  1481. end = buf->b_ml.ml_line_count;
  1482.     len = 0;
  1483.     s = buffer;
  1484.     nchars = 0;
  1485.     if (buf->b_ml.ml_flags & ML_EMPTY)
  1486. start = end + 1;
  1487.     for (lnum = start; lnum <= end; ++lnum)
  1488.     {
  1489. /*
  1490.  * The next while loop is done once for each character written.
  1491.  * Keep it fast!
  1492.  */
  1493. ptr = ml_get_buf(buf, lnum, FALSE) - 1;
  1494. while ((c = *++ptr) != NUL)
  1495. {
  1496.     if (c == NL)
  1497. *s = NUL; /* replace newlines with NULs */
  1498.     else
  1499. *s = c;
  1500.     ++s;
  1501.     if (++len != bufsize)
  1502. continue;
  1503.     if (write_buf(fd, buffer, bufsize) == FAIL)
  1504.     {
  1505. end = 0; /* write error: break loop */
  1506. break;
  1507.     }
  1508.     nchars += bufsize;
  1509.     s = buffer;
  1510.     len = 0;
  1511. }
  1512. /* write failed or last line has no EOL: stop here */
  1513. if (end == 0 || (lnum == end && buf->b_p_bin &&
  1514. (lnum == write_no_eol_lnum ||
  1515.  (lnum == buf->b_ml.ml_line_count && !buf->b_p_eol))))
  1516. {
  1517.     ++lnum; /* written the line, count it */
  1518.     no_eol = TRUE;
  1519.     break;
  1520. }
  1521. if (fileformat == EOL_UNIX)
  1522.     *s++ = NL;
  1523. else
  1524. {
  1525.     *s++ = CR; /* EOL_MAC or EOL_DOS: write CR */
  1526.     if (fileformat == EOL_DOS) /* write CR-NL */
  1527.     {
  1528. if (++len == bufsize)
  1529. {
  1530.     if (write_buf(fd, buffer, bufsize) == FAIL)
  1531.     {
  1532. end = 0; /* write error: break loop */
  1533. break;
  1534.     }
  1535.     nchars += bufsize;
  1536.     s = buffer;
  1537.     len = 0;
  1538. }
  1539. *s++ = NL;
  1540.     }
  1541. }
  1542. if (++len == bufsize && end)
  1543. {
  1544.     if (write_buf(fd, buffer, bufsize) == FAIL)
  1545.     {
  1546. end = 0; /* write error: break loop */
  1547. break;
  1548.     }
  1549.     nchars += bufsize;
  1550.     s = buffer;
  1551.     len = 0;
  1552. }
  1553.     }
  1554.     if (len && end)
  1555.     {
  1556. if (write_buf(fd, buffer, len) == FAIL)
  1557.     end = 0;     /* write error */
  1558. nchars += len;
  1559.     }
  1560.     if (close(fd) != 0)
  1561.     {
  1562. errmsg = (char_u *)"Close failed";
  1563. goto fail;
  1564.     }
  1565. #ifdef UNIX
  1566.     if (made_writable)
  1567. perm &= ~0200; /* reset 'w' bit for security reasons */
  1568. #endif
  1569.     if (perm >= 0) /* set perm. of new file same as old file */
  1570. (void)mch_setperm(fname, perm);
  1571. #ifdef RISCOS
  1572.     if (!append && !filtering)
  1573. /* Set the filetype after writing the file. */
  1574. ro_set_filetype(fname, buf->b_p_ft);
  1575. #endif
  1576.     if (end == 0)
  1577.     {
  1578. errmsg = (char_u *)"write error (file system full?)";
  1579. /*
  1580.  * If we have a backup file, try to put it in place of the new file,
  1581.  * because it is probably corrupt. This avoids loosing the original
  1582.  * file when trying to make a backup when writing the file a second
  1583.  * time.
  1584.  * For unix this means copying the backup over the new file.
  1585.  * For others this means renaming the backup file.
  1586.  * If this is OK, don't give the extra warning message.
  1587.  */
  1588. if (backup != NULL)
  1589. {
  1590. #ifdef UNIX
  1591.     char_u copybuf[BUFSIZE + 1];
  1592.     int bfd, buflen;
  1593.     if ((bfd = open((char *)backup, O_RDONLY | O_EXTRA, 0)) >= 0)
  1594.     {
  1595. if ((fd = open((char *)fname,
  1596.   O_WRONLY | O_CREAT | O_TRUNC | O_EXTRA, 0666)) >= 0)
  1597. {
  1598.     /* copy the file. */
  1599.     while ((buflen = read(bfd, (char *)copybuf, BUFSIZE)) > 0)
  1600. if (write_buf(fd, copybuf, buflen) == FAIL)
  1601.     break;
  1602.     if (close(fd) >= 0 && buflen == 0) /* success */
  1603. end = 1;
  1604. }
  1605. close(bfd); /* ignore errors for closing read file */
  1606.     }
  1607. #else
  1608.     if (vim_rename(backup, fname) == 0)
  1609. end = 1;
  1610. #endif
  1611. }
  1612. goto fail;
  1613.     }
  1614.     lnum -= start;     /* compute number of written lines */
  1615.     --no_wait_return;     /* may wait for return now */
  1616. #ifndef UNIX
  1617.     fname = sfname;     /* use shortname now, for the messages */
  1618. #endif
  1619.     if (!filtering)
  1620.     {
  1621. msg_add_fname(buf, fname); /* put fname in IObuff with quotes */
  1622. c = FALSE;
  1623. if (newfile)
  1624. {
  1625.     STRCAT(IObuff, shortmess(SHM_NEW) ? "[New]" : "[New File]");
  1626.     c = TRUE;
  1627. }
  1628. if (no_eol)
  1629. {
  1630.     msg_add_eol();
  1631.     c = TRUE;
  1632. }
  1633. /* may add [unix/dos/mac] */
  1634. if (msg_add_fileformat(fileformat))
  1635.     c = TRUE;
  1636. msg_add_lines(c, (long)lnum, nchars); /* add line/char count */
  1637. if (!shortmess(SHM_WRITE))
  1638.     STRCAT(IObuff, shortmess(SHM_WRI) ? " [w]" : " written");
  1639. keep_msg = msg_trunc_attr(IObuff, FALSE, 0);
  1640. keep_msg_attr = 0;
  1641.     }
  1642.     if (reset_changed && whole) /* when written everything */
  1643.     {
  1644. unchanged(buf, TRUE);
  1645. u_unchanged(buf);
  1646.     }
  1647.     /*
  1648.      * If written to the current file, update the timestamp of the swap file
  1649.      * and reset the 'notedited' flag. Also sets buf->b_mtime.
  1650.      */
  1651.     if (!exiting && overwriting)
  1652.     {
  1653. ml_timestamp(buf);
  1654. buf->b_notedited = FALSE;
  1655.     }
  1656.     /*
  1657.      * If we kept a backup until now, and we are in patch mode, then we make
  1658.      * the backup file our 'original' file.
  1659.      */
  1660.     if (*p_pm)
  1661.     {
  1662. char *org = (char *)buf_modname(
  1663. #ifdef SHORT_FNAME
  1664. TRUE,
  1665. #else
  1666. (buf->b_p_sn || buf->b_shortname),
  1667. #endif
  1668.   fname, p_pm, FALSE);
  1669. if (backup != NULL)
  1670. {
  1671.     struct stat st;
  1672.     /*
  1673.      * If the original file does not exist yet
  1674.      * the current backup file becomes the original file
  1675.      */
  1676.     if (org == NULL)
  1677. EMSG("patchmode: can't save original file");
  1678.     else if (stat(org, &st) < 0)
  1679.     {
  1680. vim_rename(backup, (char_u *)org);
  1681. vim_free(backup);     /* don't delete the file */
  1682. backup = NULL;
  1683. #ifdef UNIX
  1684. set_file_time((char_u *)org, st_old.st_atime, st_old.st_mtime);
  1685. #endif
  1686.     }
  1687. }
  1688. /*
  1689.  * If there is no backup file, remember that a (new) file was
  1690.  * created.
  1691.  */
  1692. else
  1693. {
  1694.     int empty_fd;
  1695.     if (org == NULL || (empty_fd = open(org, O_CREAT | O_EXTRA
  1696. #ifndef macintosh
  1697. , 0666
  1698. #endif
  1699. )) < 0)
  1700.       EMSG("patchmode: can't touch empty original file");
  1701.     else
  1702.       close(empty_fd);
  1703. }
  1704. if (org != NULL)
  1705. {
  1706.     mch_setperm((char_u *)org, mch_getperm(fname) & 0777);
  1707.     vim_free(org);
  1708. }
  1709.     }
  1710.     /*
  1711.      * Remove the backup unless 'backup' option is set
  1712.      */
  1713.     if (!p_bk && backup != NULL && mch_remove(backup) != 0)
  1714. EMSG("Can't delete backup file");
  1715.     goto nofail;
  1716. fail:
  1717.     --no_wait_return; /* may wait for return now */
  1718. nofail:
  1719.     vim_free(backup);
  1720.     if (buffer != smallbuf)
  1721. vim_free(buffer);
  1722.     if (errmsg != NULL)
  1723.     {
  1724. attr = hl_attr(HLF_E); /* set highlight for error messages */
  1725. msg_add_fname(buf,
  1726. #ifndef UNIX
  1727. sfname
  1728. #else
  1729. fname
  1730. #endif
  1731.      ); /* put file name in IObuff with quotes */
  1732. STRCAT(IObuff, errmsg);
  1733. emsg(IObuff);
  1734. retval = FAIL;
  1735. if (end == 0)
  1736. {
  1737.     MSG_PUTS_ATTR("nWARNING: Original file may be lost or damagedn",
  1738.     attr);
  1739.     MSG_PUTS_ATTR("don't quit the editor until the file is successfully written!",
  1740.     attr);
  1741. }
  1742.     }
  1743.     msg_scroll = msg_save;
  1744. #ifdef AUTOCMD
  1745.     write_no_eol_lnum = 0; /* in case it was set by the previous read */
  1746.     /*
  1747.      * Apply POST autocommands.
  1748.      * Careful: The autocommands may call buf_write() recursively!
  1749.      */
  1750.     save_buf = curbuf;
  1751.     curbuf = buf;
  1752.     curwin->w_buffer = buf;
  1753.     if (append)
  1754. apply_autocmds(EVENT_FILEAPPENDPOST, fname, fname, FALSE, curbuf);
  1755.     else if (filtering)
  1756. apply_autocmds(EVENT_FILTERWRITEPOST, NULL, fname, FALSE, curbuf);
  1757.     else if (reset_changed && whole)
  1758. apply_autocmds(EVENT_BUFWRITEPOST, fname, fname, FALSE, curbuf);
  1759.     else
  1760. apply_autocmds(EVENT_FILEWRITEPOST, fname, fname, FALSE, curbuf);
  1761.     /*
  1762.      * If the autocommands didn't change the current buffer, go back to the
  1763.      * original current buffer, if it still exists.
  1764.      */
  1765.     if (curbuf == buf && buf_valid(save_buf))
  1766.     {
  1767. curbuf = save_buf;
  1768. curwin->w_buffer = save_buf;
  1769.     }
  1770. #endif
  1771.     return retval;
  1772. }
  1773. /*
  1774.  * Put file name into IObuff with quotes.
  1775.  */
  1776.     static void
  1777. msg_add_fname(buf, fname)
  1778.     BUF     *buf;
  1779.     char_u  *fname;
  1780. {
  1781.     if (fname == NULL)
  1782. fname = (char_u *)"-stdin-";
  1783.     home_replace(buf, fname, IObuff + 1, IOSIZE - 1, TRUE);
  1784.     IObuff[0] = '"';
  1785.     STRCAT(IObuff, "" ");
  1786. }
  1787. /*
  1788.  * Append message for text mode to IObuff.
  1789.  * Return TRUE if something appended.
  1790.  */
  1791.     static int
  1792. msg_add_fileformat(eol_type)
  1793.     int     eol_type;
  1794. {
  1795. #ifndef USE_CRNL
  1796.     if (eol_type == EOL_DOS)
  1797.     {
  1798. STRCAT(IObuff, shortmess(SHM_TEXT) ? "[dos]" : "[dos format]");
  1799. return TRUE;
  1800.     }
  1801. #endif
  1802. #ifndef USE_CR
  1803.     if (eol_type == EOL_MAC)
  1804.     {
  1805. STRCAT(IObuff, shortmess(SHM_TEXT) ? "[mac]" : "[mac format]");
  1806. return TRUE;
  1807.     }
  1808. #endif
  1809. #if defined(USE_CRNL) || defined(USE_CR)
  1810.     if (eol_type == EOL_UNIX)
  1811.     {
  1812. STRCAT(IObuff, shortmess(SHM_TEXT) ? "[unix]" : "[unix format]");
  1813. return TRUE;
  1814.     }
  1815. #endif
  1816.     return FALSE;
  1817. }
  1818. /*
  1819.  * Append line and character count to IObuff.
  1820.  */
  1821.     static void
  1822. msg_add_lines(insert_space, lnum, nchars)
  1823.     int     insert_space;
  1824.     long    lnum;
  1825.     long    nchars;
  1826. {
  1827.     char_u  *p;
  1828.     p = IObuff + STRLEN(IObuff);
  1829.     if (insert_space)
  1830. *p++ = ' ';
  1831.     if (shortmess(SHM_LINES))
  1832. sprintf((char *)p, "%ldL, %ldC", lnum, nchars);
  1833.     else
  1834. sprintf((char *)p, "%ld line%s, %ld character%s",
  1835.     lnum, plural(lnum),
  1836.     nchars, plural(nchars));
  1837. }
  1838. /*
  1839.  * Append message for missing line separator to IObuff.
  1840.  */
  1841.     static void
  1842. msg_add_eol()
  1843. {
  1844.     STRCAT(IObuff, shortmess(SHM_LAST) ? "[noeol]" : "[Incomplete last line]");
  1845. }
  1846. /*
  1847.  * Check modification time of file, before writing to it.
  1848.  */
  1849.     static int
  1850. check_mtime(buf, st)
  1851.     BUF *buf;
  1852.     struct stat *st;
  1853. {
  1854.     if (buf->b_mtime_read != 0
  1855. #ifdef __linux__
  1856.     /* In Linux, on a FAT filesystem, there are only 5 bits to store
  1857.      * the seconds.  Since the roundoff is done when flushing the
  1858.      * inode, the time may change unexpectedly by one second!!! */
  1859.     && st->st_mtime - buf->b_mtime_read > 1
  1860. #else
  1861.     && buf->b_mtime_read != st->st_mtime
  1862. #endif
  1863.     )
  1864.     {
  1865. msg_scroll = TRUE;     /* don't overwrite messages here */
  1866. /* don't use emsg() here, don't want to flush the buffers */
  1867. MSG_ATTR("WARNING: The file has been changed since reading it!!!",
  1868.        hl_attr(HLF_E));
  1869. if (ask_yesno((char_u *)"Do you really want to write to it",
  1870.  TRUE) == 'n')
  1871.     return FAIL;
  1872. msg_scroll = FALSE;     /* always overwrite the file message now */
  1873.     }
  1874.     return OK;
  1875. }
  1876. /*
  1877.  * write_buf: call write() to write a buffer
  1878.  *
  1879.  * return FAIL for failure, OK otherwise
  1880.  */
  1881.     static int
  1882. write_buf(fd, buf, len)
  1883.     int     fd;
  1884.     char_u  *buf;
  1885.     int     len;
  1886. {
  1887.     int     wlen;
  1888.     while (len)
  1889.     {
  1890. wlen = write(fd, (char *)buf, (size_t)len);
  1891. if (wlen <= 0)     /* error! */
  1892.     return FAIL;
  1893. len -= wlen;
  1894. buf += wlen;
  1895.     }
  1896.     return OK;
  1897. }
  1898. /*
  1899.  * shorten_fname: Try to find a shortname by comparing the fullname with the
  1900.  * current directory.
  1901.  * Returns NULL if not shorter name possible, pointer into "full_path"
  1902.  * otherwise.
  1903.  */
  1904.     char_u *
  1905. shorten_fname(full_path, dir_name)
  1906.     char_u  *full_path;
  1907.     char_u  *dir_name;
  1908. {
  1909.     int     len;
  1910.     char_u     *p;
  1911.     if (full_path == NULL)
  1912. return NULL;
  1913.     len = STRLEN(dir_name);
  1914.     if (fnamencmp(dir_name, full_path, len) == 0)
  1915.     {
  1916. p = full_path + len;
  1917. #if defined(MSDOS) || defined(WIN32) || defined(OS2)
  1918. /*
  1919.  * MSDOS: when a file is in the root directory, dir_name will end in a
  1920.  * slash, since C: by itself does not define a specific dir. In this
  1921.  * case p may already be correct. <negri>
  1922.  */
  1923. if (!((len > 2) && (*(p - 2) == ':')))
  1924. #endif
  1925. if (vim_ispathsep(*p))
  1926.     ++p;
  1927. else
  1928.     p = NULL;
  1929.     }
  1930. #if defined(MSDOS) || defined(WIN32) || defined(OS2)
  1931.     /*
  1932.      * When using a file in the current drive, remove the drive name:
  1933.      * "A:dirfile" -> "dirfile".  This helps when moving a session file on
  1934.      * a floppy from "A:dir" to "B:dir".
  1935.      */
  1936.     else if (len > 3
  1937.     && TO_UPPER(full_path[0]) == TO_UPPER(dir_name[0])
  1938.     && full_path[1] == ':'
  1939.     && vim_ispathsep(full_path[2]))
  1940. p = full_path + 2;
  1941. #endif
  1942.     else
  1943. p = NULL;
  1944.     return p;
  1945. }
  1946. /*
  1947.  * Use full path from now on for files currently being edited, both for file
  1948.  * name and swap file name.  Try to shorten the file names a bit if safe to do
  1949.  * so.
  1950.  */
  1951.     void
  1952. shorten_fnames()
  1953. {
  1954.     char_u dirname[MAXPATHL];
  1955.     BUF *buf;
  1956.     char_u *p;
  1957.     mch_dirname(dirname, MAXPATHL);
  1958.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  1959.     {
  1960. if (buf->b_fname != NULL)
  1961. {
  1962.     vim_free(buf->b_sfname);
  1963.     buf->b_sfname = NULL;
  1964.     p = shorten_fname(buf->b_ffname, dirname);
  1965.     if (p != NULL)
  1966.     {
  1967. buf->b_sfname = vim_strsave(p);
  1968. buf->b_fname = buf->b_sfname;
  1969.     }
  1970.     if (p == NULL || buf->b_fname == NULL)
  1971. buf->b_fname = buf->b_ffname;
  1972.     mf_fullname(buf->b_ml.ml_mfp);
  1973. }
  1974.     }
  1975.     status_redraw_all();
  1976. }
  1977. /*
  1978.  * add extention to file name - change path/fo.o.h to path/fo.o.h.ext or
  1979.  * fo_o_h.ext for MSDOS or when shortname option set.
  1980.  *
  1981.  * Assumed that fname is a valid name found in the filesystem we assure that
  1982.  * the return value is a different name and ends in 'ext'.
  1983.  * "ext" MUST be at most 4 characters long if it starts with a dot, 3
  1984.  * characters otherwise.
  1985.  * Space for the returned name is allocated, must be freed later.
  1986.  * Returns NULL when out of memory.
  1987.  */
  1988.     char_u *
  1989. modname(fname, ext, prepend_dot)
  1990.     char_u *fname, *ext;
  1991.     int     prepend_dot; /* may prepend a '.' to file name */
  1992. {
  1993.     return buf_modname(
  1994. #ifdef SHORT_FNAME
  1995. TRUE,
  1996. #else
  1997. (curbuf->b_p_sn || curbuf->b_shortname),
  1998. #endif
  1999.      fname, ext, prepend_dot);
  2000. }
  2001.     char_u *
  2002. buf_modname(shortname, fname, ext, prepend_dot)
  2003.     int     shortname; /* use 8.3 file name */
  2004.     char_u  *fname, *ext;
  2005.     int     prepend_dot; /* may prepend a '.' to file name (for Unix) */
  2006. {
  2007.     char_u *retval;
  2008.     char_u *s;
  2009.     char_u *e;
  2010.     char_u *ptr;
  2011.     int fnamelen, extlen;
  2012.     extlen = STRLEN(ext);
  2013.     /*
  2014.      * If there is no file name we must get the name of the current directory
  2015.      * (we need the full path in case :cd is used).
  2016.      */
  2017.     if (fname == NULL || *fname == NUL)
  2018.     {
  2019. retval = alloc((unsigned)(MAXPATHL + extlen + 3));
  2020. if (retval == NULL)
  2021.     return NULL;
  2022. if (mch_dirname(retval, MAXPATHL) == FAIL ||
  2023.      (fnamelen = STRLEN(retval)) == 0)
  2024. {
  2025.     vim_free(retval);
  2026.     return NULL;
  2027. }
  2028. if (!vim_ispathsep(retval[fnamelen - 1]))
  2029. {
  2030.     retval[fnamelen++] = PATHSEP;
  2031.     retval[fnamelen] = NUL;
  2032. }
  2033. #ifndef SHORT_FNAME
  2034. prepend_dot = FALSE;     /* nothing to prepend a dot to */
  2035. #endif
  2036.     }
  2037.     else
  2038.     {
  2039. fnamelen = STRLEN(fname);
  2040. retval = alloc((unsigned)(fnamelen + extlen + 3));
  2041. if (retval == NULL)
  2042.     return NULL;
  2043. STRCPY(retval, fname);
  2044.     }
  2045.     /*
  2046.      * search backwards until we hit a '/', '' or ':' replacing all '.'
  2047.      * by '_' for MSDOS or when shortname option set and ext starts with a dot.
  2048.      * Then truncate what is after the '/', '' or ':' to 8 characters for
  2049.      * MSDOS and 26 characters for AMIGA, a lot more for UNIX.
  2050.      */
  2051.     for (ptr = retval + fnamelen; ptr >= retval; ptr--)
  2052.     {
  2053. #ifndef RISCOS
  2054. if (*ext == '.'
  2055. #ifdef USE_LONG_FNAME
  2056.     && (!USE_LONG_FNAME || shortname)
  2057. #else
  2058. # ifndef SHORT_FNAME
  2059.     && shortname
  2060. # endif
  2061. #endif
  2062. )
  2063.     if (*ptr == '.') /* replace '.' by '_' */
  2064. *ptr = '_';
  2065. #endif /* RISCOS */
  2066. if (vim_ispathsep(*ptr))
  2067.     break;
  2068.     }
  2069.     ptr++;
  2070.     /* the file name has at most BASENAMELEN characters. */
  2071. #ifndef SHORT_FNAME
  2072.     if (STRLEN(ptr) > (unsigned)BASENAMELEN)
  2073. ptr[BASENAMELEN] = '';
  2074. #endif
  2075.     s = ptr + STRLEN(ptr);
  2076.     /*
  2077.      * For 8.3 file names we may have to reduce the length.
  2078.      */
  2079. #ifdef USE_LONG_FNAME
  2080.     if (!USE_LONG_FNAME || shortname)
  2081. #else
  2082. # ifndef SHORT_FNAME
  2083.     if (shortname)
  2084. # endif
  2085. #endif
  2086.     {
  2087. /*
  2088.  * If there is no file name, or the file name ends in '/', and the
  2089.  * extension starts with '.', put a '_' before the dot, because just
  2090.  * ".ext" is invalid.
  2091.  */
  2092. if (fname == NULL || *fname == NUL
  2093.    || vim_ispathsep(fname[STRLEN(fname) - 1]))
  2094. {
  2095. #ifdef RISCOS
  2096.     if (*ext == '/')
  2097. #else
  2098.     if (*ext == '.')
  2099. #endif
  2100. *s++ = '_';
  2101. }
  2102. /*
  2103.  * If the extension starts with '.', truncate the base name at 8
  2104.  * characters
  2105.  */
  2106. #ifdef RISCOS
  2107. /* We normally use '/', but swap files are '_' */
  2108. else if (*ext == '/' || *ext == '_')
  2109. #else
  2110. else if (*ext == '.')
  2111. #endif
  2112. {
  2113.     if (s - ptr > (size_t)8)
  2114.     {
  2115. s = ptr + 8;
  2116. *s = '';
  2117.     }
  2118. }
  2119. /*
  2120.  * If the extension doesn't start with '.', and the file name
  2121.  * doesn't have an extension yet, append a '.'
  2122.  */
  2123. #ifdef RISCOS
  2124. else if ((e = vim_strchr(ptr, '/')) == NULL)
  2125.     *s++ = '/';
  2126. #else
  2127. else if ((e = vim_strchr(ptr, '.')) == NULL)
  2128.     *s++ = '.';
  2129. #endif
  2130. /*
  2131.  * If the extension doesn't start with '.', and there already is an
  2132.  * extension, it may need to be tructated
  2133.  */
  2134. else if ((int)STRLEN(e) + extlen > 4)
  2135.     s = e + 4 - extlen;
  2136.     }
  2137. #if defined(OS2) || defined(USE_LONG_FNAME) || defined(WIN32)
  2138.     /*
  2139.      * If there is no file name, and the extension starts with '.', put a
  2140.      * '_' before the dot, because just ".ext" may be invalid if it's on a
  2141.      * FAT partition, and on HPFS it doesn't matter.
  2142.      */
  2143.     else if ((fname == NULL || *fname == NUL) && *ext == '.')
  2144. *s++ = '_';
  2145. #endif
  2146.     /*
  2147.      * Append the extention.
  2148.      * ext can start with '.' and cannot exceed 3 more characters.
  2149.      */
  2150.     STRCPY(s, ext);
  2151. #ifndef SHORT_FNAME
  2152.     /*
  2153.      * Prepend the dot.
  2154.      */
  2155.     if (prepend_dot && !shortname && *(e = gettail(retval)) !=
  2156. #ifdef RISCOS
  2157.     '/'
  2158. #else
  2159.     '.'
  2160. #endif
  2161. #ifdef USE_LONG_FNAME
  2162.     && USE_LONG_FNAME
  2163. #endif
  2164. )
  2165.     {
  2166. mch_memmove(e + 1, e, STRLEN(e) + 1);
  2167. #ifdef RISCOS
  2168. *e = '/';
  2169. #else
  2170. *e = '.';
  2171. #endif
  2172.     }
  2173. #endif
  2174.     /*
  2175.      * Check that, after appending the extension, the file name is really
  2176.      * different.
  2177.      */
  2178.     if (fname != NULL && STRCMP(fname, retval) == 0)
  2179.     {
  2180. /* we search for a character that can be replaced by '_' */
  2181. while (--s >= ptr)
  2182. {
  2183.     if (*s != '_')
  2184.     {
  2185. *s = '_';
  2186. break;
  2187.     }
  2188. }
  2189. if (s < ptr) /* fname was "________.<ext>" how tricky! */
  2190.     *ptr = 'v';
  2191.     }
  2192.     return retval;
  2193. }
  2194. /* vim_fgets();
  2195.  *
  2196.  * Like fgets(), but if the file line is too long, it is truncated and the
  2197.  * rest of the line is thrown away.  Returns TRUE for end-of-file.
  2198.  * Note: do not pass IObuff as the buffer since this is used to read and
  2199.  * discard the extra part of any long lines.
  2200.  */
  2201.     int
  2202. vim_fgets(buf, size, fp)
  2203.     char_u *buf;
  2204.     int size;
  2205.     FILE *fp;
  2206. {
  2207.     char *eof;
  2208.     buf[size - 2] = NUL;
  2209.     eof = fgets((char *)buf, size, fp);
  2210.     if (buf[size - 2] != NUL && buf[size - 2] != 'n')
  2211.     {
  2212. buf[size - 1] = NUL;     /* Truncate the line */
  2213. /* Now throw away the rest of the line: */
  2214. do
  2215. {
  2216.     IObuff[IOSIZE - 2] = NUL;
  2217.     fgets((char *)IObuff, IOSIZE, fp);
  2218. } while (IObuff[IOSIZE - 2] != NUL && IObuff[IOSIZE - 2] != 'n');
  2219.     }
  2220.     return (eof == NULL);
  2221. }
  2222. /*
  2223.  * rename() only works if both files are on the same file system, this
  2224.  * function will (attempts to?) copy the file across if rename fails -- webb
  2225.  * Return -1 for failure, 0 for success.
  2226.  */
  2227.     int
  2228. vim_rename(from, to)
  2229.     char_u *from;
  2230.     char_u *to;
  2231. {
  2232.     int     fd_in;
  2233.     int     fd_out;
  2234.     int     n;
  2235.     char    *errmsg = NULL;
  2236.     char    *buffer;
  2237.     /*
  2238.      * First delete the "to" file, this is required on some systems to make
  2239.      * the mch_rename() work, on other systems it makes sure that we don't
  2240.      * have two files when the mch_rename() fails.
  2241.      */
  2242.     mch_remove(to);
  2243.     /*
  2244.      * First try a normal rename, return if it works.
  2245.      */
  2246.     if (mch_rename((char *)from, (char *)to) == 0)
  2247. return 0;
  2248.     /*
  2249.      * Rename() failed, try copying the file.
  2250.      */
  2251.     fd_in = open((char *)from, O_RDONLY | O_EXTRA
  2252. #ifndef macintosh
  2253. , 0
  2254. #endif
  2255. );
  2256.     if (fd_in == -1)
  2257. return -1;
  2258.     fd_out = open((char *)to, O_CREAT | O_TRUNC | O_WRONLY | O_EXTRA
  2259. #ifndef macintosh
  2260. , 0666
  2261. #endif
  2262. );
  2263.     if (fd_out == -1)
  2264.     {
  2265. close(fd_in);
  2266. return -1;
  2267.     }
  2268.     buffer = (char *)alloc(BUFSIZE);
  2269.     if (buffer == NULL)
  2270.     {
  2271. close(fd_in);
  2272. close(fd_out);
  2273. return -1;
  2274.     }
  2275.     while ((n = read(fd_in, buffer, (size_t)BUFSIZE)) > 0)
  2276. if (write(fd_out, buffer, (size_t)n) != n)
  2277. {
  2278.     errmsg = "writing to";
  2279.     break;
  2280. }
  2281.     vim_free(buffer);
  2282.     close(fd_in);
  2283.     if (close(fd_out) < 0)
  2284. errmsg = "closing";
  2285.     if (n < 0)
  2286.     {
  2287. errmsg = "reading";
  2288. to = from;
  2289.     }
  2290.     if (errmsg != NULL)
  2291.     {
  2292. sprintf((char *)IObuff, "Error %s '%s'", errmsg, to);
  2293. emsg(IObuff);
  2294. return -1;
  2295.     }
  2296.     mch_remove(from);
  2297.     return 0;
  2298. }
  2299. /*
  2300.  * Check if any not hidden buffer has been changed.
  2301.  * Postpone the check if there are characters in the stuff buffer, a global
  2302.  * command is being executed, a mapping is being executed or an autocommand is
  2303.  * busy.
  2304.  */
  2305.     void
  2306. check_timestamps()
  2307. {
  2308.     BUF     *buf;
  2309.     if (!stuff_empty() || global_busy || !typebuf_typed()
  2310. #ifdef AUTOCMD
  2311. || autocmd_busy
  2312. #endif
  2313. )
  2314. need_check_timestamps = TRUE; /* check later */
  2315.     else
  2316.     {
  2317. ++no_wait_return;
  2318. for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  2319.     buf_check_timestamp(buf);
  2320. --no_wait_return;
  2321. need_check_timestamps = FALSE;
  2322. if (need_wait_return) /* make sure the message isn't overwritten */
  2323.     msg_puts((char_u *)"n");
  2324.     }
  2325. }
  2326. /*
  2327.  * Check if buffer "buf" has been changed.
  2328.  */
  2329.     void
  2330. buf_check_timestamp(buf)
  2331.     BUF     *buf;
  2332. {
  2333.     struct stat     st;
  2334.     char_u     *path;
  2335.     if (    buf->b_ffname != NULL
  2336.     && buf->b_ml.ml_mfp != NULL
  2337.     && !buf->b_notedited
  2338.     && buf->b_mtime != 0
  2339.     && stat((char *)buf->b_ffname, &st) >= 0
  2340. #ifdef __linux__
  2341.     /* In Linux, on a FAT filesystem, there are only 5 bits to
  2342.      * store the seconds.  Since the roundoff is done when
  2343.      * flushing the inode, the time may change unexpectedly by one
  2344.      * second!!! */
  2345.     && st.st_mtime - buf->b_mtime > 1
  2346. #else
  2347.     && buf->b_mtime != st.st_mtime
  2348. #endif
  2349.     )
  2350.     {
  2351. #ifdef AUTOCMD
  2352. /*
  2353.  * Only give the warning if there are no FileChangedShell autocommands.
  2354.  */
  2355. if (!apply_autocmds(EVENT_FILECHANGEDSHELL,
  2356.       buf->b_fname, buf->b_fname, FALSE, buf))
  2357. #endif
  2358. {
  2359.     path = home_replace_save(buf, buf->b_fname);
  2360.     if (path != NULL)
  2361.     {
  2362. EMSG2("Warning: File "%s" has changed since editing started",
  2363.     path);
  2364. vim_free(path);
  2365.     }
  2366. }
  2367. buf->b_mtime = st.st_mtime;
  2368.     }
  2369. }
  2370. /*
  2371.  * Adjust the line with missing eol, used for the next write.
  2372.  * Used for do_filter(), when the input lines for the filter are deleted.
  2373.  */
  2374.     void
  2375. write_lnum_adjust(offset)
  2376.     linenr_t offset;
  2377. {
  2378.     if (write_no_eol_lnum) /* only if there is a missing eol */
  2379. write_no_eol_lnum += offset;
  2380. }
  2381. /*
  2382.  * vim_tempname(): Return a unique name that can be used for a temp file.
  2383.  *
  2384.  * The temp file is NOT created.
  2385.  *
  2386.  * The returned pointer is to allocated memory.
  2387.  * The returned pointer is NULL if no valid name was found.
  2388.  */
  2389.     char_u  *
  2390. vim_tempname(extra_char)
  2391.     int     extra_char;     /* character to use in the name instead of '?' */
  2392. {
  2393. #ifdef USE_GUI_WIN32
  2394. # undef USE_TMPNAM
  2395. # define TEMPNAMELEN 256
  2396.     char szTempFile[_MAX_PATH+1];
  2397. #endif
  2398. #ifdef USE_TMPNAM
  2399.     char_u itmp[L_tmpnam]; /* use tmpnam() */
  2400. #else
  2401.     char_u itmp[TEMPNAMELEN];
  2402. #endif
  2403. #if defined(TEMPDIRNAMES) || (!defined(USE_GUI_WIN32) && !defined(USE_TMPNAM))
  2404.     char_u     *p;
  2405. #endif
  2406. #ifdef TEMPDIRNAMES
  2407.     static char *(tempdirs[]) = {TEMPDIRNAMES};
  2408.     static int first_dir = 0;
  2409.     int first_try = TRUE;
  2410.     int i;
  2411.     /*
  2412.      * Try a few places to put the temp file.
  2413.      * To avoid waisting time with non-existing environment variables and
  2414.      * directories, they are skipped next time.
  2415.      */
  2416.     for (i = first_dir; i < sizeof(tempdirs) / sizeof(char *); ++i)
  2417.     {
  2418. /* expand $TMP, leave room for '/', "v?XXXXXX" and NUL */
  2419. expand_env((char_u *)tempdirs[i], itmp, TEMPNAMELEN - 10);
  2420. if (mch_isdir(itmp)) /* directory exists */
  2421. {
  2422.     if (first_try)
  2423. first_dir = i; /* start here next time */
  2424.     first_try = FALSE;
  2425. #ifdef __EMX__
  2426.     /*
  2427.      * if $TMP contains a forward slash (perhaps because we're using
  2428.      * bash or tcsh, right Stefan?), don't add a backslash to the
  2429.      * directory before tacking on the file name; use a forward slash!
  2430.      * I first tried adding 2 backslashes, but somehow that didn't
  2431.      * work (something in the EMX system() ate them, I think).
  2432.      */
  2433.     if (vim_strchr(itmp, '/'))
  2434. STRCAT(itmp, "/");
  2435.     else
  2436. #endif
  2437. STRCAT(itmp, PATHSEPSTR);
  2438.     STRCAT(itmp, TEMPNAME);
  2439.     if ((p = vim_strchr(itmp, '?')) != NULL)
  2440. *p = extra_char;
  2441.     if (*mktemp((char *)itmp) == NUL)
  2442. continue;
  2443.     return vim_strsave(itmp);
  2444. }
  2445.     }
  2446.     return NULL;
  2447. #else /* !TEMPDIRNAMES */
  2448. # ifdef USE_GUI_WIN32
  2449.     STRCPY(itmp, "");
  2450.     GetTempPath(_MAX_PATH, szTempFile);
  2451.     if (GetTempFileName(szTempFile, "VIM", 0, itmp) == 0)
  2452. # else
  2453. #  ifdef USE_TMPNAM
  2454.     /* tmpnam() will make its own name */
  2455.     if (*tmpnam((char *)itmp) == NUL)
  2456. #  else
  2457. #   ifdef VMS
  2458.     /* mktemp() is not working on VMS.  It seems to be
  2459.      * a do-nothing function. Therefore we use tempnam().
  2460.      */
  2461.     sprintf((char *)itmp, "VIM%c", extra_char);
  2462.     p = (char_u *)tempnam("tmp:", (char *)itmp);
  2463.     if (p != NULL)
  2464.     {
  2465. /* VMS will use '.LOG' if we don't explicitly specify an extension,
  2466.  * and VIM will then be unable to find the file later */
  2467. STRCPY(itmp, p);
  2468. STRCAT(itmp, ".txt");
  2469. free(p);
  2470.     }
  2471.     else
  2472. #   else
  2473.     STRCPY(itmp, TEMPNAME);
  2474.     if ((p = vim_strchr(itmp, '?')) != NULL)
  2475. *p = extra_char;
  2476.     if (*mktemp((char *)itmp) == NUL)
  2477. #   endif
  2478. #  endif
  2479. # endif
  2480. return NULL;
  2481. # ifdef WIN32
  2482.     {
  2483. char_u *p;
  2484. char_u *retval;
  2485. /* backslashes in a temp file name cause problems when filtering with
  2486.  * "sh" */
  2487. retval = vim_strsave(itmp);
  2488. if (*p_shcf == '-')
  2489.     for (p = retval; *p; ++p)
  2490. if (*p == '\')
  2491.     *p = '/';
  2492. return retval;
  2493.     }
  2494. # else
  2495.     return vim_strsave(itmp);
  2496. # endif
  2497. #endif /* !TEMPDIRNAMES */
  2498. }
  2499. /*
  2500.  * Code for automatic commands.
  2501.  *
  2502.  * Only included when "AUTOCMD" has been defined.
  2503.  */
  2504. #ifdef AUTOCMD
  2505. /*
  2506.  * The autocommands are stored in a list for each event.
  2507.  * Autocommands for the same pattern, that are consecutive, are joined
  2508.  * together, to avoid having to match the pattern too often.
  2509.  * The result is an array of Autopat lists, which point to AutoCmd lists:
  2510.  *
  2511.  * first_autopat[0] --> Autopat.next  -->  Autopat.next -->  NULL
  2512.  * Autopat.cmds    Autopat.cmds
  2513.  *     |  |
  2514.  *     V  V
  2515.  * AutoCmd.next    AutoCmd.next
  2516.  *     |  |
  2517.  *     V  V
  2518.  * AutoCmd.next NULL
  2519.  *     |
  2520.  *     V
  2521.  *    NULL
  2522.  *
  2523.  * first_autopat[1] --> Autopat.next  -->  NULL
  2524.  * Autopat.cmds
  2525.  *     |
  2526.  *     V
  2527.  * AutoCmd.next
  2528.  *     |
  2529.  *     V
  2530.  *    NULL
  2531.  *   etc.
  2532.  *
  2533.  *   The order of AutoCmds is important, this is the order in which they were
  2534.  *   defined and will have to be executed.
  2535.  */
  2536. typedef struct AutoCmd
  2537. {
  2538.     char_u     *cmd; /* The command to be executed (NULL
  2539.    when command has been removed) */
  2540.     char     nested; /* If autocommands nest here */
  2541.     char     last; /* last command in list */
  2542.     struct AutoCmd  *next; /* Next AutoCmd in list */
  2543. } AutoCmd;
  2544. typedef struct AutoPat
  2545. {
  2546.     int     group; /* group ID */
  2547.     char_u     *pat; /* pattern as typed (NULL when pattern
  2548.    has been removed) */
  2549.     char_u     *reg_pat; /* pattern converted to regexp */
  2550.     char     allow_dirs; /* Pattern may match whole path */
  2551.     char     last; /* last pattern for apply_autocmds() */
  2552.     AutoCmd     *cmds; /* list of commands to do */
  2553.     struct AutoPat  *next; /* next AutoPat in AutoPat list */
  2554. } AutoPat;
  2555. static struct event_name
  2556. {
  2557.     char *name;     /* event name */
  2558.     EVENT_T event;     /* event number */
  2559. } event_names[] =
  2560. {
  2561.     {"BufDelete", EVENT_BUFDELETE},
  2562.     {"BufEnter", EVENT_BUFENTER},
  2563.     {"BufFilePost", EVENT_BUFFILEPOST},
  2564.     {"BufFilePre", EVENT_BUFFILEPRE},
  2565.     {"BufLeave", EVENT_BUFLEAVE},
  2566.     {"BufNewFile", EVENT_BUFNEWFILE},
  2567.     {"BufReadPost", EVENT_BUFREADPOST},
  2568.     {"BufReadPre", EVENT_BUFREADPRE},
  2569.     {"BufRead", EVENT_BUFREADPOST},
  2570.     {"BufUnload", EVENT_BUFUNLOAD},
  2571.     {"BufWritePost", EVENT_BUFWRITEPOST},
  2572.     {"BufWritePre", EVENT_BUFWRITEPRE},
  2573.     {"BufWrite", EVENT_BUFWRITEPRE},
  2574.     {"FileAppendPost", EVENT_FILEAPPENDPOST},
  2575.     {"FileAppendPre", EVENT_FILEAPPENDPRE},
  2576.     {"FileChangedShell",    EVENT_FILECHANGEDSHELL},
  2577.     {"FileEncoding",    EVENT_FILEENCODING},
  2578.     {"FileReadPost", EVENT_FILEREADPOST},
  2579.     {"FileReadPre", EVENT_FILEREADPRE},
  2580.     {"FileWritePost", EVENT_FILEWRITEPOST},
  2581.     {"FileWritePre", EVENT_FILEWRITEPRE},
  2582.     {"FilterReadPost", EVENT_FILTERREADPOST},
  2583.     {"FilterReadPre", EVENT_FILTERREADPRE},
  2584.     {"FilterWritePost", EVENT_FILTERWRITEPOST},
  2585.     {"FilterWritePre", EVENT_FILTERWRITEPRE},
  2586.     {"StdinReadPost", EVENT_STDINREADPOST},
  2587.     {"StdinReadPre", EVENT_STDINREADPRE},
  2588.     {"TermChanged", EVENT_TERMCHANGED},
  2589.     {"User", EVENT_USER},
  2590.     {"VimEnter", EVENT_VIMENTER},
  2591.     {"VimLeave", EVENT_VIMLEAVE},
  2592.     {"VimLeavePre", EVENT_VIMLEAVEPRE},
  2593.     {"WinEnter", EVENT_WINENTER},
  2594.     {"WinLeave", EVENT_WINLEAVE},
  2595.     {NULL, (EVENT_T)0}
  2596. };
  2597. static AutoPat *first_autopat[NUM_EVENTS] =
  2598. {
  2599.     NULL, NULL, NULL, NULL, NULL,
  2600.     NULL, NULL, NULL, NULL, NULL,
  2601.     NULL, NULL, NULL, NULL, NULL,
  2602.     NULL, NULL, NULL, NULL, NULL,
  2603.     NULL
  2604. };
  2605. /*
  2606.  * struct used to keep status while executing autocommands for an event.
  2607.  */
  2608. typedef struct AutoPatCmd
  2609. {
  2610.     AutoPat *curpat; /* next AutoPat to examine */
  2611.     AutoCmd *nextcmd; /* next AutoCmd to execute */
  2612.     int group; /* group being used */
  2613.     char_u *fname; /* fname to match with */
  2614.     char_u *sfname; /* sfname to match with */
  2615.     char_u *tail; /* tail of fname */
  2616.     EVENT_T event; /* current event */
  2617. } AutoPatCmd;
  2618. /*
  2619.  * augroups stores a list of autocmd group names.
  2620.  */
  2621. struct growarray augroups = {0, 0, sizeof(char_u *), 10, NULL};
  2622. #define AUGROUP_NAME(i) (((char_u **)augroups.ga_data)[i])
  2623. /*
  2624.  * The ID of the current group.  Group 0 is the default one.
  2625.  */
  2626. #define AUGROUP_DEFAULT     -1     /* default autocmd group */
  2627. #define AUGROUP_ERROR     -2     /* errornouse autocmd group */
  2628. #define AUGROUP_ALL     -3     /* all autocmd groups */
  2629. static int current_augroup = AUGROUP_DEFAULT;
  2630. static int au_need_clean = FALSE;   /* need to delete marked patterns */
  2631. static void show_autocmd __ARGS((AutoPat *ap, EVENT_T event));
  2632. static void au_remove_pat __ARGS((AutoPat *ap));
  2633. static void au_remove_cmds __ARGS((AutoPat *ap));
  2634. static void au_cleanup __ARGS((void));
  2635. static int au_find_group __ARGS((char_u *name));
  2636. static int au_new_group __ARGS((char_u *name));
  2637. static int au_find_group __ARGS((char_u *name));
  2638. static EVENT_T event_name2nr __ARGS((char_u *start, char_u **end));
  2639. static char_u *event_nr2name __ARGS((EVENT_T event));
  2640. static char_u *find_end_event __ARGS((char_u *arg));
  2641. static int event_ignored __ARGS((EVENT_T event));
  2642. static int au_get_grouparg __ARGS((char_u **argp));
  2643. static int do_autocmd_event __ARGS((EVENT_T event, char_u *pat, int nested, char_u *cmd, int forceit, int group));
  2644. static int apply_autocmds_group __ARGS((EVENT_T event, char_u *fname, char_u *fname_io, int force, int group, BUF *buf));
  2645. static char_u *getnextac __ARGS((int c, void *cookie, int indent));
  2646. static void auto_next_pat __ARGS((AutoPatCmd *apc, int stop_at_last));
  2647. static EVENT_T last_event;
  2648. static int last_group;
  2649. /*
  2650.  * Show the autocommands for one AutoPat.
  2651.  */
  2652.     static void
  2653. show_autocmd(ap, event)
  2654.     AutoPat *ap;
  2655.     EVENT_T event;
  2656. {
  2657.     AutoCmd *ac;
  2658.     if (got_int) /* "q" hit for "--more--" */
  2659. return;
  2660.     if (ap->pat == NULL) /* pattern has been removed */
  2661. return;
  2662.     msg_putchar('n');
  2663.     if (got_int) /* "q" hit for "--more--" */
  2664. return;
  2665.     if (event != last_event || ap->group != last_group)
  2666.     {
  2667. if (ap->group != AUGROUP_DEFAULT)
  2668. {
  2669.     msg_puts_attr(AUGROUP_NAME(ap->group), hl_attr(HLF_T));
  2670.     msg_puts((char_u *)"  ");
  2671. }
  2672. msg_puts_attr(event_nr2name(event), hl_attr(HLF_T));
  2673. last_event = event;
  2674. last_group = ap->group;
  2675. msg_putchar('n');
  2676. if (got_int) /* "q" hit for "--more--" */
  2677.     return;
  2678.     }
  2679.     msg_col = 4;
  2680.     msg_outtrans(ap->pat);
  2681.     for (ac = ap->cmds; ac != NULL; ac = ac->next)
  2682.     {
  2683. if (ac->cmd != NULL) /* skip removed commands */
  2684. {
  2685.     if (msg_col >= 14)
  2686. msg_putchar('n');
  2687.     msg_col = 14;
  2688.     if (got_int) /* "q" hit for "--more--" */
  2689. return;
  2690.     msg_outtrans(ac->cmd);
  2691.     if (got_int) /* "q" hit for "--more--" */
  2692. return;
  2693.     if (ac->next != NULL)
  2694.     {
  2695. msg_putchar('n');
  2696. if (got_int) /* "q" hit for "--more--" */
  2697.     return;
  2698.     }
  2699. }
  2700.     }
  2701. }
  2702. /*
  2703.  * Mark an autocommand pattern for deletion.
  2704.  */
  2705.     static void
  2706. au_remove_pat(ap)
  2707.     AutoPat *ap;
  2708. {
  2709.     vim_free(ap->pat);
  2710.     ap->pat = NULL;
  2711.     au_need_clean = TRUE;
  2712. }
  2713. /*
  2714.  * Mark all commands for a pattern for deletion.
  2715.  */
  2716.     static void
  2717. au_remove_cmds(ap)
  2718.     AutoPat *ap;
  2719. {
  2720.     AutoCmd *ac;
  2721.     for (ac = ap->cmds; ac != NULL; ac = ac->next)
  2722.     {
  2723. vim_free(ac->cmd);
  2724. ac->cmd = NULL;
  2725.     }
  2726.     au_need_clean = TRUE;
  2727. }
  2728. /*
  2729.  * Cleanup autocommands and patterns that have been deleted.
  2730.  * This is only done when not executing autocommands.
  2731.  */
  2732.     static void
  2733. au_cleanup()
  2734. {
  2735.     AutoPat *ap, **prev_ap;
  2736.     AutoCmd *ac, **prev_ac;
  2737.     EVENT_T event;
  2738.     if (autocmd_busy || !au_need_clean)
  2739. return;
  2740.     /* loop over all events */
  2741.     for (event = (EVENT_T)0; (int)event < (int)NUM_EVENTS;
  2742.     event = (EVENT_T)((int)event + 1))
  2743.     {
  2744. /* loop over all autocommand patterns */
  2745. prev_ap = &(first_autopat[(int)event]);
  2746. for (ap = *prev_ap; ap != NULL; ap = *prev_ap)
  2747. {
  2748.     /* loop over all commands for this pattern */
  2749.     prev_ac = &(ap->cmds);
  2750.     for (ac = *prev_ac; ac != NULL; ac = *prev_ac)
  2751.     {
  2752. /* remove the command if the pattern is to be deleted or when
  2753.  * the command has been marked for deletion */
  2754. if (ap->pat == NULL || ac->cmd == NULL)
  2755. {
  2756.     *prev_ac = ac->next;
  2757.     vim_free(ac->cmd);
  2758.     vim_free(ac);
  2759. }
  2760. else
  2761.     prev_ac = &(ac->next);
  2762.     }
  2763.     /* remove the pattern if it has been marked for deletion */
  2764.     if (ap->pat == NULL)
  2765.     {
  2766. *prev_ap = ap->next;
  2767. vim_free(ap->reg_pat);
  2768. vim_free(ap);
  2769.     }
  2770.     else
  2771. prev_ap = &(ap->next);
  2772. }
  2773.     }
  2774.     au_need_clean = FALSE;
  2775. }
  2776. /*
  2777.  * Add an autocmd group name.
  2778.  * Return it's ID.  Returns AUGROUP_ERROR for error.
  2779.  */
  2780.     static int
  2781. au_new_group(name)
  2782.     char_u *name;
  2783. {
  2784.     int     i;
  2785.     i = au_find_group(name);
  2786.     if (i == AUGROUP_ERROR) /* the group doesn't exist yet, add it */
  2787.     {
  2788. if (ga_grow(&augroups, 1) == FAIL)
  2789.     return AUGROUP_ERROR;
  2790. i = augroups.ga_len;
  2791. AUGROUP_NAME(i) = vim_strsave(name);
  2792. if (AUGROUP_NAME(i) == NULL)
  2793.     return AUGROUP_ERROR;
  2794. ++augroups.ga_len;
  2795. --augroups.ga_room;
  2796.     }
  2797.     return i;
  2798. }
  2799. /*
  2800.  * Find the ID of an autocmd group name.
  2801.  * Return it's ID.  Returns AUGROUP_ERROR for error.
  2802.  */
  2803.     static int
  2804. au_find_group(name)
  2805.     char_u *name;
  2806. {
  2807.     int     i;
  2808.     for (i = 0; i < augroups.ga_len; ++i)
  2809.     {
  2810. if (AUGROUP_NAME(i) != NULL && STRCMP(AUGROUP_NAME(i), name) == 0)
  2811.     return i;
  2812.     }
  2813.     return AUGROUP_ERROR;
  2814. }
  2815. /*
  2816.  * Implementation of the ":augroup name" command.
  2817.  */
  2818.     void
  2819. do_augroup(arg)
  2820.     char_u *arg;
  2821. {
  2822.     int     i;
  2823.     if (STRICMP(arg, "end") == 0)   /* ":aug end": back to group 0 */
  2824. current_augroup = AUGROUP_DEFAULT;
  2825.     else if (*arg)     /* ":aug xxx": switch to group xxx */
  2826.     {
  2827. i = au_new_group(arg);
  2828. if (i != AUGROUP_ERROR)
  2829.     current_augroup = i;
  2830.     }
  2831.     else     /* ":aug": list the group names */
  2832.     {
  2833. msg_start();
  2834. for (i = 0; i < augroups.ga_len; ++i)
  2835. {
  2836.     if (AUGROUP_NAME(i) != NULL)
  2837.     {
  2838. msg_puts(AUGROUP_NAME(i));
  2839. msg_puts((char_u *)"  ");
  2840.     }
  2841. }
  2842. msg_clr_eos();
  2843. msg_end();
  2844.     }
  2845. }
  2846. /*
  2847.  * Function given to ExpandGeneric() to obtain the list of autocommand group
  2848.  * names.
  2849.  */
  2850.     char_u *
  2851. get_augroup_name(idx)
  2852.     int     idx;
  2853. {
  2854.     if (idx == augroups.ga_len) /* add "END" add the end */
  2855. return (char_u *)"END";
  2856.     if (idx >= augroups.ga_len) /* end of list */
  2857. return NULL;
  2858.     if (AUGROUP_NAME(idx) == NULL) /* skip deleted entries */
  2859. return (char_u *)"";
  2860.     return AUGROUP_NAME(idx); /* return a name */
  2861. }
  2862. /*
  2863.  * Return the event number for event name "start".
  2864.  * Return NUM_EVENTS if the event name was not found.
  2865.  * Return a pointer to the next event name in "end".
  2866.  */
  2867.     static EVENT_T
  2868. event_name2nr(start, end)
  2869.     char_u  *start;
  2870.     char_u  **end;
  2871. {
  2872.     char_u *p;
  2873.     int i;
  2874.     int len;
  2875.     /* the event name ends with end of line, a blank or a comma */
  2876.     for (p = start; *p && !vim_iswhite(*p) && *p != ','; ++p)
  2877. ;
  2878.     for (i = 0; event_names[i].name != NULL; ++i)
  2879.     {
  2880. len = strlen(event_names[i].name);
  2881. if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0)
  2882.     break;
  2883.     }
  2884.     if (*p == ',')
  2885. ++p;
  2886.     *end = p;
  2887.     if (event_names[i].name == NULL)
  2888. return NUM_EVENTS;
  2889.     return event_names[i].event;
  2890. }
  2891. /*
  2892.  * Return the name for event "event".
  2893.  */
  2894.     static char_u *
  2895. event_nr2name(event)
  2896.     EVENT_T event;
  2897. {
  2898.     int     i;
  2899.     for (i = 0; event_names[i].name != NULL; ++i)
  2900. if (event_names[i].event == event)
  2901.     return (char_u *)event_names[i].name;
  2902.     return (char_u *)"Unknown";
  2903. }
  2904. /*
  2905.  * Scan over the events.  "*" stands for all events.
  2906.  */
  2907.     static char_u *
  2908. find_end_event(arg)
  2909.     char_u  *arg;
  2910. {
  2911.     char_u  *pat;
  2912.     char_u  *p;
  2913.     if (*arg == '*')
  2914.     {
  2915. if (arg[1] && !vim_iswhite(arg[1]))
  2916. {
  2917.     EMSG2("Illegal character after *: %s", arg);
  2918.     return NULL;
  2919. }
  2920. pat = arg + 1;
  2921.     }
  2922.     else
  2923.     {
  2924. for (pat = arg; *pat && !vim_iswhite(*pat); pat = p)
  2925. {
  2926.     if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS)
  2927.     {
  2928. EMSG2("No such event: %s", pat);
  2929. return NULL;
  2930.     }
  2931. }
  2932.     }
  2933.     return pat;
  2934. }
  2935. /*
  2936.  * Return TRUE if "event" is included in 'eventignore'.
  2937.  */
  2938.     static int
  2939. event_ignored(event)
  2940.     EVENT_T event;
  2941. {
  2942.     char_u *p = p_ei;
  2943.     if (STRICMP(p_ei, "all") == 0)
  2944. return TRUE;
  2945.     while (*p)
  2946. if (event_name2nr(p, &p) == event)
  2947.     return TRUE;
  2948.     return FALSE;
  2949. }
  2950. /*
  2951.  * Return OK when the contents of p_ei is valid, FAIL otherwise.
  2952.  */
  2953.     int
  2954. check_ei()
  2955. {
  2956.     char_u *p = p_ei;
  2957.     if (STRICMP(p_ei, "all") == 0)
  2958. return OK;
  2959.     while (*p)
  2960. if (event_name2nr(p, &p) == NUM_EVENTS)
  2961.     return FAIL;
  2962.     return OK;
  2963. }
  2964. /*
  2965.  * do_autocmd() -- implements the :autocmd command.  Can be used in the
  2966.  *  following ways:
  2967.  *
  2968.  * :autocmd <event> <pat> <cmd>     Add <cmd> to the list of commands that
  2969.  *     will be automatically executed for <event>
  2970.  *     when editing a file matching <pat>, in
  2971.  *     the current group.
  2972.  * :autocmd <event> <pat>     Show the auto-commands associated with
  2973.  *     <event> and <pat>.
  2974.  * :autocmd <event>     Show the auto-commands associated with
  2975.  *     <event>.
  2976.  * :autocmd     Show all auto-commands.
  2977.  * :autocmd! <event> <pat> <cmd>    Remove all auto-commands associated with
  2978.  *     <event> and <pat>, and add the command
  2979.  *     <cmd>, for the current group.
  2980.  * :autocmd! <event> <pat>     Remove all auto-commands associated with
  2981.  *     <event> and <pat> for the current group.
  2982.  * :autocmd! <event>     Remove all auto-commands associated with
  2983.  *     <event> for the current group.
  2984.  * :autocmd!     Remove ALL auto-commands for the current
  2985.  *     group.
  2986.  *
  2987.  *  Multiple events and patterns may be given separated by commas.  Here are
  2988.  *  some examples:
  2989.  * :autocmd bufread,bufenter *.c,*.h set tw=0 smartindent noic
  2990.  * :autocmd bufleave      * set tw=79 nosmartindent ic infercase
  2991.  *
  2992.  * :autocmd * *.c show all autocommands for *.c files.
  2993.  */
  2994.     void
  2995. do_autocmd(arg, forceit)
  2996.     char_u  *arg;
  2997.     int     forceit;
  2998. {
  2999.     char_u *pat;
  3000.     char_u *envpat = NULL;
  3001.     char_u *cmd;
  3002.     EVENT_T event;
  3003.     int need_free = FALSE;
  3004.     int nested = FALSE;
  3005.     int group;
  3006.     /*
  3007.      * Check for a legal group name.  If not, use AUGROUP_ALL.
  3008.      */
  3009.     group = au_get_grouparg(&arg);
  3010.     if (arg == NULL)     /* out of memory */
  3011. return;
  3012.     /*
  3013.      * Scan over the events.
  3014.      * If we find an illegal name, return here, don't do anything.
  3015.      */
  3016.     pat = find_end_event(arg);
  3017.     if (pat == NULL)
  3018. return;
  3019.     /*
  3020.      * Scan over the pattern.  Put a NUL at the end.
  3021.      */
  3022.     pat = skipwhite(pat);
  3023.     cmd = pat;
  3024.     while (*cmd && (!vim_iswhite(*cmd) || cmd[-1] == '\'))
  3025. cmd++;
  3026.     if (*cmd)
  3027. *cmd++ = NUL;
  3028.     /* expand environment variables in the pattern */
  3029.     if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL)
  3030.     {
  3031. envpat = expand_env_save(pat);
  3032. if (envpat != NULL)
  3033.     pat = envpat;
  3034.     }
  3035.     /*
  3036.      * Check for "nested" flag.
  3037.      */
  3038.     cmd = skipwhite(cmd);
  3039.     if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && vim_iswhite(cmd[6]))
  3040.     {
  3041. nested = TRUE;
  3042. cmd = skipwhite(cmd + 6);
  3043.     }
  3044.     /*
  3045.      * Find the start of the commands.
  3046.      * Expand <sfile> in it.
  3047.      */
  3048.     if (*cmd != NUL)
  3049.     {
  3050. cmd = expand_sfile(cmd);
  3051. if (cmd == NULL)     /* some error */
  3052.     return;
  3053. need_free = TRUE;
  3054.     }
  3055.     /*
  3056.      * Print header when showing autocommands.
  3057.      */
  3058.     if (!forceit && *cmd == NUL)
  3059.     {
  3060. /* Highlight title */
  3061. MSG_PUTS_TITLE("n--- Auto-Commands ---");
  3062.     }
  3063.     /*
  3064.      * Loop over the events.
  3065.      */
  3066.     last_event = (EVENT_T)-1; /* for listing the event name */
  3067.     last_group = AUGROUP_ERROR; /* for listing the group name */
  3068.     if (*arg == '*' || *arg == NUL)
  3069.     {
  3070. for (event = (EVENT_T)0; (int)event < (int)NUM_EVENTS;
  3071.     event = (EVENT_T)((int)event + 1))
  3072.     if (do_autocmd_event(event, pat,
  3073.  nested, cmd, forceit, group) == FAIL)
  3074. break;
  3075.     }
  3076.     else
  3077.     {
  3078. while (*arg && !vim_iswhite(*arg))
  3079.     if (do_autocmd_event(event_name2nr(arg, &arg), pat,
  3080. nested, cmd, forceit, group) == FAIL)
  3081. break;
  3082.     }
  3083.     if (need_free)
  3084. vim_free(cmd);
  3085.     vim_free(envpat);
  3086. }
  3087. /*
  3088.  * Find the group ID in a ":autocmd" or ":doautocmd" argument.
  3089.  * The "argp" argument is advanced to the following argument.
  3090.  *
  3091.  * Returns the group ID, AUGROUP_ERROR for error (out of memory).
  3092.  */
  3093.     static int
  3094. au_get_grouparg(argp)
  3095.     char_u **argp;
  3096. {
  3097.     char_u *group_name;
  3098.     char_u *p;
  3099.     char_u *arg = *argp;
  3100.     int group = AUGROUP_ALL;
  3101.     p = skiptowhite(arg);
  3102.     if (p > arg)
  3103.     {
  3104. group_name = vim_strnsave(arg, (int)(p - arg));
  3105. if (group_name == NULL) /* out of memory */
  3106.     return AUGROUP_ERROR;
  3107. group = au_find_group(group_name);
  3108. if (group == AUGROUP_ERROR)
  3109.     group = AUGROUP_ALL; /* no match, use all groups */
  3110. else
  3111.     *argp = skipwhite(p); /* match, skip over group name */
  3112. vim_free(group_name);
  3113.     }
  3114.     return group;
  3115. }
  3116. /*
  3117.  * do_autocmd() for one event.
  3118.  * If *pat == NUL do for all patterns.
  3119.  * If *cmd == NUL show entries.
  3120.  * If forceit == TRUE delete entries.
  3121.  * If group is not AUGROUP_ALL, only use this group.
  3122.  */
  3123.     static int
  3124. do_autocmd_event(event, pat, nested, cmd, forceit, group)
  3125.     EVENT_T event;
  3126.     char_u *pat;
  3127.     int nested;
  3128.     char_u *cmd;
  3129.     int forceit;
  3130.     int group;
  3131. {
  3132.     AutoPat *ap;
  3133.     AutoPat **prev_ap;
  3134.     AutoCmd *ac;
  3135.     AutoCmd **prev_ac;
  3136.     int brace_level;
  3137.     char_u *endpat;
  3138.     int len;
  3139.     /*
  3140.      * Show or delete all patterns for an event.
  3141.      */
  3142.     if (*pat == NUL)
  3143.     {
  3144. for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
  3145. {
  3146.     if (forceit)  /* delete the AutoPat, if it's in the current group */
  3147.     {
  3148. if (ap->group == (group == AUGROUP_ALL ? current_augroup
  3149.        : group))
  3150.     au_remove_pat(ap);
  3151.     }
  3152.     else if (group == AUGROUP_ALL || ap->group == group)
  3153. show_autocmd(ap, event);
  3154. }
  3155.     }
  3156.     /*
  3157.      * Loop through all the specified patterns.
  3158.      */
  3159.     for ( ; *pat; pat = (*endpat == ',' ? endpat + 1 : endpat))
  3160.     {
  3161. /*
  3162.  * Find end of the pattern.
  3163.  * Watch out for a comma in braces, like "*.{obj,o}".
  3164.  */
  3165. brace_level = 0;
  3166. for (endpat = pat; *endpat && (*endpat != ',' || brace_level
  3167.      || endpat[-1] == '\'); ++endpat)
  3168. {
  3169.     if (*endpat == '{')
  3170. brace_level++;
  3171.     else if (*endpat == '}')
  3172. brace_level--;
  3173. }
  3174. if (pat == endpat) /* ignore single comma */
  3175.     continue;
  3176. /*
  3177.  * Find AutoPat entries with this pattern.
  3178.  */
  3179. prev_ap = &first_autopat[(int)event];
  3180. while ((ap = *prev_ap) != NULL)
  3181. {
  3182.     if (ap->pat != NULL)
  3183.     {
  3184. /* Accept a pattern when:
  3185.  * - a group was specified and it's that group, or a group was
  3186.  *   not specified and it's the current group, or a group was
  3187.  *   not specified and we are listing
  3188.  * - the length of the pattern matches
  3189.  * - the pattern matches
  3190.  */
  3191. len = STRLEN(ap->pat);
  3192. if ((ap->group == (group == AUGROUP_ALL ? current_augroup
  3193. : group)
  3194.    || (group == AUGROUP_ALL && !forceit && *cmd == NUL))
  3195. && len == endpat - pat
  3196. && STRNCMP(pat, ap->pat, len) == 0)
  3197. {
  3198.     /*
  3199.      * Remove existing autocommands.
  3200.      * If adding any new autocmd's for this AutoPat, don't
  3201.      * delete the pattern from the autopat list, append to
  3202.      * this list.
  3203.      */
  3204.     if (forceit)
  3205.     {
  3206. if (*cmd != NUL && ap->next == NULL)
  3207. {
  3208.     au_remove_cmds(ap);
  3209.     break;
  3210. }
  3211. au_remove_pat(ap);
  3212.     }
  3213.     /*
  3214.      * Show autocmd's for this autopat
  3215.      */
  3216.     else if (*cmd == NUL)
  3217. show_autocmd(ap, event);
  3218.     /*
  3219.      * Add autocmd to this autopat, if it's the last one.
  3220.      */
  3221.     else if (ap->next == NULL)
  3222. break;
  3223. }
  3224.     }
  3225.     prev_ap = &ap->next;
  3226. }
  3227. /*
  3228.  * Add a new command.
  3229.  */
  3230. if (*cmd != NUL)
  3231. {
  3232.     /*
  3233.      * If the pattern we want to add a command to does appear at the
  3234.      * end of the list (or not is not in the list at all), add the
  3235.      * pattern at the end of the list.
  3236.      */
  3237.     if (ap == NULL)
  3238.     {
  3239. ap = (AutoPat *)alloc((unsigned)sizeof(AutoPat));
  3240. if (ap == NULL)
  3241.     return FAIL;
  3242. ap->pat = vim_strnsave(pat, (int)(endpat - pat));
  3243. if (ap->pat == NULL)
  3244. {
  3245.     vim_free(ap);
  3246.     return FAIL;
  3247. }
  3248. ap->reg_pat = file_pat_to_reg_pat(pat, endpat, &ap->allow_dirs);
  3249. if (ap->reg_pat == NULL)
  3250. {
  3251.     vim_free(ap->pat);
  3252.     vim_free(ap);
  3253.     return FAIL;
  3254. }
  3255. ap->cmds = NULL;
  3256. *prev_ap = ap;
  3257. ap->next = NULL;
  3258. if (group == AUGROUP_ALL)
  3259.     ap->group = current_augroup;
  3260. else
  3261.     ap->group = group;
  3262.     }
  3263.     /*
  3264.      * Add the autocmd at the end of the AutoCmd list.
  3265.      */
  3266.     prev_ac = &(ap->cmds);
  3267.     while ((ac = *prev_ac) != NULL)
  3268. prev_ac = &ac->next;
  3269.     ac = (AutoCmd *)alloc((unsigned)sizeof(AutoCmd));
  3270.     if (ac == NULL)
  3271. return FAIL;
  3272.     ac->cmd = vim_strsave(cmd);
  3273.     if (ac->cmd == NULL)
  3274.     {
  3275. vim_free(ac);
  3276. return FAIL;
  3277.     }
  3278.     ac->next = NULL;
  3279.     *prev_ac = ac;
  3280.     ac->nested = nested;
  3281. }
  3282.     }
  3283.     au_cleanup(); /* may really delete removed patterns/commands now */
  3284.     return OK;
  3285. }
  3286. /*
  3287.  * Implementation of ":doautocmd [group] event [fname]".
  3288.  * Return OK for success, FAIL for failure;
  3289.  */
  3290.     int
  3291. do_doautocmd(arg, do_msg)
  3292.     char_u *arg;
  3293.     int do_msg;     /* give message for no matching autocmds? */
  3294. {
  3295.     char_u *fname;
  3296.     int nothing_done = TRUE;
  3297.     int group;
  3298.     /*
  3299.      * Check for a legal group name.  If not, use AUGROUP_ALL.
  3300.      */
  3301.     group = au_get_grouparg(&arg);
  3302.     if (arg == NULL)     /* out of memory */
  3303. return FAIL;
  3304.     if (*arg == '*')
  3305.     {
  3306. EMSG("Can't execute autocommands for ALL events");
  3307. return FAIL;
  3308.     }
  3309.     /*
  3310.      * Scan over the events.
  3311.      * If we find an illegal name, return here, don't do anything.
  3312.      */
  3313.     fname = find_end_event(arg);
  3314.     if (fname == NULL)
  3315. return FAIL;
  3316.     fname = skipwhite(fname);
  3317.     /*
  3318.      * Loop over the events.
  3319.      */
  3320.     while (*arg && !vim_iswhite(*arg))
  3321. if (apply_autocmds_group(event_name2nr(arg, &arg),
  3322.     fname, NULL, TRUE, group, curbuf))
  3323.     nothing_done = FALSE;
  3324.     if (nothing_done && do_msg)
  3325. MSG("No matching autocommands");
  3326.     return OK;
  3327. }
  3328. /*
  3329.  * ":doautoall" command: execute autocommands for each loaded buffer.
  3330.  */
  3331.     void
  3332. do_autoall(arg)
  3333.     char_u *arg;
  3334. {
  3335.     BUF *save_buf = NULL;
  3336.     WIN *win;
  3337.     WIN *save_curwin = NULL;
  3338.     int retval;
  3339.     FPOS save_cursor;
  3340.     linenr_t save_topline = 0;
  3341.     int len;
  3342.     save_cursor.lnum = 0;   /* init for gcc */
  3343.     save_cursor.col = 0;
  3344.     /*
  3345.      * This is a bit tricky: For some commands curwin->w_buffer needs to be
  3346.      * equal to curbuf, but for some buffers there may not be a window.
  3347.      * So we change the buffer for the current window for a moment.  This
  3348.      * gives problems when the autocommands make changes to the list of
  3349.      * buffers or windows...
  3350.      */
  3351.     for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
  3352.     {
  3353. if (curbuf->b_ml.ml_mfp != NULL)
  3354. {
  3355.     for (win = firstwin; win != NULL; win = win->w_next)
  3356. if (win->w_buffer == curbuf)
  3357.     break;
  3358.     /* if there is a window for this buffer, make it the curwin */
  3359.     if (win != NULL)
  3360.     {
  3361. save_curwin = curwin;
  3362. curwin = win;
  3363.     }
  3364.     else
  3365.     {
  3366. /* if there is no window for this buffer, use curwin */
  3367. --curwin->w_buffer->b_nwindows;
  3368. save_buf = curwin->w_buffer;
  3369. curwin->w_buffer = curbuf;
  3370. ++curwin->w_buffer->b_nwindows;
  3371. /* set cursor and topline to safe values */
  3372. save_cursor = curwin->w_cursor;
  3373. curwin->w_cursor.lnum = 1;
  3374. curwin->w_cursor.col = 0;
  3375. save_topline = curwin->w_topline;
  3376. curwin->w_topline = 1;
  3377.     }
  3378.     retval = do_doautocmd(arg, FALSE);
  3379.     do_modelines();
  3380.     if (win != NULL)     /* restore curwin */
  3381.     {
  3382. if (win_valid(save_curwin))
  3383.     curwin = save_curwin;
  3384.     }
  3385.     else     /* restore buffer for curwin */
  3386.     {
  3387. if (buf_valid(save_buf))
  3388. {
  3389.     --curwin->w_buffer->b_nwindows;
  3390.     curwin->w_buffer = save_buf;
  3391.     ++save_buf->b_nwindows;
  3392.     if (save_cursor.lnum <= save_buf->b_ml.ml_line_count)
  3393.     {
  3394. curwin->w_cursor = save_cursor;
  3395. len = STRLEN(ml_get_buf(save_buf,
  3396.        curwin->w_cursor.lnum, FALSE));
  3397. if (len == 0)
  3398.     curwin->w_cursor.col = 0;
  3399. else if ((int)curwin->w_cursor.col >= len)
  3400.     curwin->w_cursor.col = len - 1;
  3401.     }
  3402.     else
  3403.     {
  3404. curwin->w_cursor.lnum = save_buf->b_ml.ml_line_count;
  3405. curwin->w_cursor.col = 0;
  3406.     }
  3407.     /* check topline < line_count, in case lines got deleted */
  3408.     if (save_topline <= save_buf->b_ml.ml_line_count)
  3409. curwin->w_topline = save_topline;
  3410.     else
  3411. curwin->w_topline = save_buf->b_ml.ml_line_count;
  3412. }
  3413.     }
  3414.     if (retval == FAIL)
  3415. break;
  3416. }
  3417.     }
  3418.     curbuf = curwin->w_buffer;
  3419.     adjust_cursor();     /* just in case lines got deleted */
  3420. }
  3421. static int autocmd_nested = FALSE;
  3422. /*
  3423.  * Execute autocommands for "event" and file name "fname".
  3424.  * Return TRUE if some commands were executed.
  3425.  */
  3426.     int
  3427. apply_autocmds(event, fname, fname_io, force, buf)
  3428.     EVENT_T event;
  3429.     char_u *fname;     /* NULL or empty means use actual file name */
  3430.     char_u *fname_io;  /* fname to use for <afile> on cmdline */
  3431.     int force;     /* when TRUE, ignore autocmd_busy */
  3432.     BUF *buf;     /* buffer for <abuf> */
  3433. {
  3434.     return apply_autocmds_group(event, fname, fname_io, force,
  3435.     AUGROUP_ALL, buf);
  3436. }
  3437.     static int
  3438. apply_autocmds_group(event, fname, fname_io, force, group, buf)
  3439.     EVENT_T event;
  3440.     char_u *fname;     /* NULL or empty means use actual file name */
  3441.     char_u *fname_io;  /* fname to use for <afile> on cmdline */
  3442.     int force;     /* when TRUE, ignore autocmd_busy */
  3443.     int group;     /* group ID, or AUGROUP_ALL */
  3444.     BUF *buf;     /* buffer for <abuf> */
  3445. {
  3446.     char_u     *sfname = NULL; /* short file name */
  3447.     char_u     *tail;
  3448.     int     temp;
  3449.     int     save_changed = curbuf->b_changed;
  3450.     BUF     *old_curbuf = curbuf;
  3451.     int     retval = FALSE;
  3452.     char_u     *save_sourcing_name;
  3453.     char_u     *save_autocmd_fname = autocmd_fname;
  3454.     int     save_autocmd_bufnr = autocmd_bufnr;
  3455.     int     save_autocmd_busy = autocmd_busy;
  3456.     int     save_autocmd_nested = autocmd_nested;
  3457.     static int     nesting = 0;
  3458.     AutoPatCmd     patcmd;
  3459.     AutoPat     *ap;
  3460. #ifdef WANT_EVAL
  3461.     void     *save_funccalp;
  3462. #endif
  3463.     /*
  3464.      * When autocommands are busy, new autocommands are only executed when
  3465.      * explicitly enabled with the "nested" flag.
  3466.      */
  3467.     if (autocmd_busy && !(force || autocmd_nested))
  3468. return retval;
  3469.     /*
  3470.      * Ignore events in 'eventignore'.
  3471.      */
  3472.     if (event_ignored(event))
  3473. return retval;
  3474.     /*
  3475.      * Allow nesting of autocommands, but restrict the depth, because it's
  3476.      * possible to create an endless loop.
  3477.      */
  3478.     if (nesting == 10)
  3479.     {
  3480. EMSG("autocommand nesting too deep");
  3481. return retval;
  3482.     }
  3483.     /*
  3484.      * Check if these autocommands are disabled.  Used when doing ":all" or
  3485.      * ":ball".
  3486.      */
  3487.     if (    (autocmd_no_enter &&
  3488. (event == EVENT_WINENTER || event == EVENT_BUFENTER)) ||
  3489.     (autocmd_no_leave &&
  3490. (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE)))
  3491. return retval;
  3492.     /*
  3493.      * Set the file name to be used for <afile>.
  3494.      */
  3495.     if (fname_io == NULL)
  3496.     {
  3497. if (fname != NULL && *fname != NUL)
  3498.     autocmd_fname = fname;
  3499. else if (buf != NULL)
  3500.     autocmd_fname = buf->b_fname;
  3501. else
  3502.     autocmd_fname = NULL;
  3503.     }
  3504.     else
  3505. autocmd_fname = fname_io;
  3506.     if (buf == NULL)
  3507. autocmd_bufnr = 0;
  3508.     else
  3509. autocmd_bufnr = buf->b_fnum;
  3510.     /*
  3511.      * When the file name is NULL or empty, use the file name of buffer "buf".
  3512.      * Always use the full path of the file name to match with, in case
  3513.      * "allow_dirs" is set.
  3514.      */
  3515.     if (fname == NULL || *fname == NUL)
  3516.     {
  3517. if (buf == NULL)
  3518.     fname = NULL;
  3519. else
  3520. {
  3521.     if (buf->b_sfname != NULL)
  3522. sfname = vim_strsave(buf->b_sfname);
  3523.     fname = buf->b_ffname;
  3524. }
  3525. if (fname == NULL)
  3526.     fname = (char_u *)"";
  3527. fname = vim_strsave(fname); /* make a copy, so we can change it */
  3528.     }
  3529.     else
  3530.     {
  3531. sfname = vim_strsave(fname);
  3532. fname = FullName_save(fname, FALSE);
  3533.     }
  3534.     if (fname == NULL)     /* out of memory */
  3535.     {
  3536. vim_free(sfname);
  3537. return FALSE;
  3538.     }
  3539. #ifdef BACKSLASH_IN_FILENAME
  3540.     /*
  3541.      * Replace all backslashes with forward slashes.  This makes the
  3542.      * autocommand patterns portable between Unix and MS-DOS.
  3543.      */
  3544.     {
  3545. char_u     *p;
  3546. if (sfname != NULL)
  3547. {
  3548.     for (p = sfname; *p; ++p)
  3549. if (*p == '\')
  3550.     *p = '/';
  3551. }
  3552. for (p = fname; *p; ++p)
  3553.     if (*p == '\')
  3554. *p = '/';
  3555.     }
  3556. #endif
  3557.     /* Don't redraw while doing auto commands. */
  3558.     temp = RedrawingDisabled;
  3559.     RedrawingDisabled = TRUE;
  3560.     save_sourcing_name = sourcing_name;
  3561.     sourcing_name = NULL; /* don't free this one */
  3562. #ifdef WANT_EVAL
  3563.     /* Don't use local function variables, if called from a function */
  3564.     save_funccalp = save_funccal();
  3565. #endif
  3566.     /*
  3567.      * When starting to execute autocommands, save the search patterns.
  3568.      */
  3569.     if (!autocmd_busy)
  3570.     {
  3571. save_search_patterns();
  3572. saveRedobuff();
  3573.     }
  3574.     /*
  3575.      * Note that we are applying autocmds.  Some commands need to know.
  3576.      */
  3577.     autocmd_busy = TRUE;
  3578.     ++nesting;
  3579.     tail = gettail(fname);
  3580.     /* Find first autocommand that matches */
  3581.     patcmd.curpat = first_autopat[(int)event];
  3582.     patcmd.nextcmd = NULL;
  3583.     patcmd.group = group;
  3584.     patcmd.fname = fname;
  3585.     patcmd.sfname = sfname;
  3586.     patcmd.tail = tail;
  3587.     patcmd.event = event;
  3588.     auto_next_pat(&patcmd, FALSE);
  3589.     /* found one, start executing the autocommands */
  3590.     if (patcmd.curpat != NULL)
  3591.     {
  3592. retval = TRUE;
  3593. /* mark the last pattern, to avoid an endless loop when more patterns
  3594.  * are added when executing autocommands */
  3595. for (ap = patcmd.curpat; ap->next != NULL; ap = ap->next)
  3596.     ap->last = FALSE;
  3597. ap->last = TRUE;
  3598. check_lnums(TRUE); /* make sure cursor and topline are valid */
  3599. do_cmdline(NULL, getnextac, (void *)&patcmd,
  3600.      DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
  3601.     }
  3602.     RedrawingDisabled = temp;
  3603.     autocmd_busy = save_autocmd_busy;
  3604.     autocmd_nested = save_autocmd_nested;
  3605.     vim_free(sourcing_name);
  3606.     sourcing_name = save_sourcing_name;
  3607.     autocmd_fname = save_autocmd_fname;
  3608.     autocmd_bufnr = save_autocmd_bufnr;
  3609. #ifdef WANT_EVAL
  3610.     restore_funccal(save_funccalp);
  3611. #endif
  3612.     vim_free(fname);
  3613.     vim_free(sfname);
  3614.     --nesting;
  3615.     /*
  3616.      * When stopping to execute autocommands, restore the search patterns and
  3617.      * the redo buffer.
  3618.      */
  3619.     if (!autocmd_busy)
  3620.     {
  3621. restore_search_patterns();
  3622. restoreRedobuff();
  3623.     }
  3624.     /*
  3625.      * Some events don't set or reset the Changed flag.
  3626.      * Check if still in the same buffer!
  3627.      */
  3628.     if (curbuf == old_curbuf
  3629.     && (event == EVENT_BUFREADPOST
  3630. || event == EVENT_BUFWRITEPOST
  3631. || event == EVENT_FILEAPPENDPOST
  3632. || event == EVENT_VIMLEAVE
  3633. || event == EVENT_VIMLEAVEPRE))
  3634. curbuf->b_changed = save_changed;
  3635.     au_cleanup(); /* may really delete removed patterns/commands now */
  3636.     return retval;
  3637. }
  3638. /*
  3639.  * Find next autocommand pattern that matches.
  3640.  */
  3641.     static void
  3642. auto_next_pat(apc, stop_at_last)
  3643.     AutoPatCmd *apc;
  3644.     int stop_at_last;     /* stop when 'last' flag is set */
  3645. {
  3646.     AutoPat *ap;
  3647.     AutoCmd *cp;
  3648.     char_u *name;
  3649.     vim_free(sourcing_name);
  3650.     sourcing_name = NULL;
  3651.     for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next)
  3652.     {
  3653. apc->curpat = NULL;
  3654. /* only use a pattern when it has not been removed, has commands and
  3655.  * the group matches */
  3656. if (ap->pat != NULL && ap->cmds != NULL
  3657. && (apc->group == AUGROUP_ALL || apc->group == ap->group))
  3658. {
  3659.     if (match_file_pat(ap->reg_pat, apc->fname, apc->sfname, apc->tail,
  3660.       ap->allow_dirs))
  3661.     {
  3662. name = event_nr2name(apc->event);
  3663. sourcing_name = alloc((unsigned)(STRLEN(name)
  3664.      + STRLEN(ap->pat) + 25));
  3665. if (sourcing_name != NULL)
  3666. {
  3667.     sprintf((char *)sourcing_name,
  3668.     "%s Auto commands for "%s"",
  3669.        (char *)name, (char *)ap->pat);
  3670.     if (p_verbose >= 8)
  3671. smsg((char_u *)"Executing %s", sourcing_name);
  3672. }
  3673. apc->curpat = ap;
  3674. apc->nextcmd = ap->cmds;
  3675. /* mark last command */
  3676. for (cp = ap->cmds; cp->next != NULL; cp = cp->next)
  3677.     cp->last = FALSE;
  3678. cp->last = TRUE;
  3679.     }
  3680.     line_breakcheck();
  3681.     if (apc->curpat != NULL)     /* found a match */
  3682. break;
  3683. }
  3684. if (stop_at_last && ap->last)
  3685.     break;
  3686.     }
  3687. }
  3688. /*
  3689.  * Get next autocommand command.
  3690.  * Called by do_cmdline() to get the next line for ":if".
  3691.  * Returns allocated string, or NULL for end of autocommands.
  3692.  */
  3693. /* ARGSUSED */
  3694.     static char_u *
  3695. getnextac(c, cookie, indent)
  3696.     int     c;     /* not used */
  3697.     void    *cookie;
  3698.     int     indent;     /* not used */
  3699. {
  3700.     AutoPatCmd     *acp = (AutoPatCmd *)cookie;
  3701.     char_u     *retval;
  3702.     /* repeat until we find an autocommand to execute */
  3703.     for (;;)
  3704.     {
  3705. /* skip removed commands */
  3706. while (acp->nextcmd != NULL && acp->nextcmd->cmd == NULL)
  3707.     if (acp->nextcmd->last)
  3708. acp->nextcmd = NULL;
  3709.     else
  3710. acp->nextcmd = acp->nextcmd->next;
  3711. if (acp->nextcmd != NULL)
  3712.     break;
  3713. /* at end of commands, find next pattern that matches */
  3714. if (acp->curpat->last)
  3715.     acp->curpat = NULL;
  3716. else
  3717.     acp->curpat = acp->curpat->next;
  3718. if (acp->curpat != NULL)
  3719.     auto_next_pat(acp, TRUE);
  3720. if (acp->curpat == NULL)
  3721.     return NULL;
  3722.     }
  3723.     if (p_verbose >= 9)
  3724.     {
  3725. msg_scroll = TRUE;     /* always scroll up, don't overwrite */
  3726. smsg((char_u *)"autocommand %s", acp->nextcmd->cmd);
  3727. msg_puts((char_u *)"n");   /* don't overwrite this either */
  3728. cmdline_row = msg_row;
  3729.     }
  3730.     retval = vim_strsave(acp->nextcmd->cmd);
  3731.     autocmd_nested = acp->nextcmd->nested;
  3732.     if (acp->nextcmd->last)
  3733. acp->nextcmd = NULL;
  3734.     else
  3735. acp->nextcmd = acp->nextcmd->next;
  3736.     return retval;
  3737. }
  3738. static int include_groups = FALSE;
  3739.     char_u  *
  3740. set_context_in_autocmd(arg, doautocmd)
  3741.     char_u  *arg;
  3742.     int     doautocmd;     /* TRUE for :doautocmd, FALSE for :autocmd */
  3743. {
  3744.     char_u  *p;
  3745.     int     group;
  3746.     /* check for a group name, skip it if present */
  3747.     include_groups = FALSE;
  3748.     group = au_get_grouparg(&arg);
  3749.     if (group == AUGROUP_ERROR)
  3750. return NULL;
  3751.     /* skip over event name */
  3752.     for (p = arg; *p && !vim_iswhite(*p); ++p)
  3753. if (*p == ',')
  3754.     arg = p + 1;
  3755.     if (*p == NUL)
  3756.     {
  3757. if (group == AUGROUP_ALL)
  3758.     include_groups = TRUE;
  3759. expand_context = EXPAND_EVENTS;     /* expand event name */
  3760. expand_pattern = arg;
  3761. return NULL;
  3762.     }
  3763.     /* skip over pattern */
  3764.     arg = skipwhite(p);
  3765.     while (*arg && (!vim_iswhite(*arg) || arg[-1] == '\'))
  3766. arg++;
  3767.     if (*arg)
  3768. return arg;     /* expand (next) command */
  3769.     if (doautocmd)
  3770. expand_context = EXPAND_FILES;     /* expand file names */
  3771.     else
  3772. expand_context = EXPAND_NOTHING;    /* pattern is not expanded */
  3773.     return NULL;
  3774. }
  3775. /*
  3776.  * Function given to ExpandGeneric() to obtain the list of event names.
  3777.  */
  3778.     char_u *
  3779. get_event_name(idx)
  3780.     int     idx;
  3781. {
  3782.     if (idx < augroups.ga_len) /* First list group names, if wanted */
  3783.     {
  3784. if (!include_groups || AUGROUP_NAME(idx) == NULL)
  3785.     return (char_u *)""; /* skip deleted entries */
  3786. return AUGROUP_NAME(idx); /* return a name */
  3787.     }
  3788.     return (char_u *)event_names[idx - augroups.ga_len].name;
  3789. }
  3790. #endif /* AUTOCMD */
  3791. #if defined(AUTOCMD) || defined(WILDIGNORE)
  3792. /*
  3793.  * Try matching a filename with a pattern.
  3794.  * Used for autocommands and 'wildignore'.
  3795.  * Returns TRUE if there is a match, FALSE otherwise.
  3796.  */
  3797.     int
  3798. match_file_pat(pattern, fname, sfname, tail, allow_dirs)
  3799.     char_u *pattern; /* pattern to match with */
  3800.     char_u *fname; /* full path of file name */
  3801.     char_u *sfname; /* short file name */
  3802.     char_u *tail; /* tail of path */
  3803.     int allow_dirs; /* allow matching with dir */
  3804. {
  3805.     vim_regexp *prog;
  3806.     int result = FALSE;
  3807. #ifdef WANT_FILETYPE
  3808.     int no_pattern = FALSE; /* TRUE if check is filetype only */
  3809.     char_u *type_start;
  3810.     char_u c;
  3811.     int match = FALSE;
  3812. #endif
  3813. #ifdef CASE_INSENSITIVE_FILENAME
  3814.     reg_ic = TRUE; /* Always ignore case */
  3815. #else
  3816.     reg_ic = FALSE; /* Don't ever ignore case */
  3817. #endif
  3818. #ifdef WANT_FILETYPE
  3819.     if (*pattern == '<')
  3820.     {
  3821. /* There is a filetype condition specified with this pattern.
  3822.  * Check the filetype matches first. If not, don't
  3823.  * bother with the pattern. (set prog = NULL)
  3824.  */
  3825. for (type_start = pattern + 1; (c = *pattern); pattern++)
  3826. {
  3827.     if ((c == ';' || c == '>') && match == FALSE)
  3828.     {
  3829. *pattern = NUL;     /* Terminate the string */
  3830. match = mch_check_filetype(fname, type_start);
  3831. *pattern = c;     /* Restore the terminator */
  3832. type_start = pattern + 1;
  3833.     }
  3834.     if (c == '>')
  3835. break;
  3836. }
  3837. /* (c should never be NUL, but check anyway) */
  3838. if (match == FALSE || c == NUL)
  3839.     prog = NULL; /* Doesn't match - don't check pat. */
  3840. else if (*pattern == NUL)
  3841. {
  3842.     prog = NULL; /* Vim will try to free prog later */
  3843.     no_pattern = TRUE; /* Always matches - don't check pat. */
  3844. }
  3845. else
  3846.     prog = vim_regcomp(pattern + 1, TRUE);/* Always use magic */
  3847.     }
  3848.     else
  3849. prog = vim_regcomp(pattern, TRUE); /* Always use magic */
  3850. #else
  3851.     prog = vim_regcomp(pattern, TRUE); /* Always use magic */
  3852. #endif
  3853.     /*
  3854.      * Try for a match with the pattern with:
  3855.      * 1. the full file name, when the pattern has a '/'.
  3856.      * 2. the short file name, when the pattern has a '/'.
  3857.      * 3. the tail of the file name, when the pattern has no '/'.
  3858.      */
  3859.     if (
  3860. #ifdef WANT_FILETYPE
  3861.     /* If the check is for a filetype only and we don't care
  3862.      * about the path then skip all the regexp stuff.
  3863.      */
  3864.     no_pattern ||
  3865. #endif
  3866.     (prog != NULL
  3867.      && ((allow_dirs
  3868.      && (vim_regexec(prog, fname, TRUE)
  3869.  || (sfname != NULL
  3870.      && vim_regexec(prog, sfname, TRUE))))
  3871.  || (!allow_dirs
  3872.      && vim_regexec(prog, tail, TRUE)))))
  3873. result = TRUE;
  3874.     vim_free(prog);
  3875.     return result;
  3876. }
  3877. #endif
  3878. /*
  3879.  * Convert the given pattern "pat" which has shell style wildcards in it, into
  3880.  * a regular expression, and return the result in allocated memory.  If there
  3881.  * is a directory path separator to be matched, then TRUE is put in
  3882.  * allow_dirs, otherwise FALSE is put there -- webb.
  3883.  *
  3884.  * If WANT_FILETYPE defined then pass initial <type> through unchanged. Eg:
  3885.  * '<html>myfile' becomes '<html>^myfile$' -- leonard.
  3886.  *
  3887.  * Returns NULL when out of memory.
  3888.  */
  3889.     char_u *
  3890. file_pat_to_reg_pat(pat, pat_end, allow_dirs)
  3891.     char_u  *pat;
  3892.     char_u  *pat_end; /* first char after pattern */
  3893.     char    *allow_dirs; /* Result passed back out in here */
  3894. {
  3895.     int size;
  3896.     char_u *endp;
  3897.     char_u *reg_pat;
  3898.     char_u *p;
  3899.     int i;
  3900.     int nested = 0;
  3901.     int add_dollar = TRUE;
  3902. #ifdef WANT_FILETYPE
  3903.     int check_length = 0;
  3904. #endif
  3905.     if (allow_dirs != NULL)
  3906. *allow_dirs = FALSE;
  3907. #ifdef WANT_FILETYPE
  3908.     /* Find out how much of the string is the filetype check */
  3909.     if (*pat == '<')
  3910.     {
  3911. /* Count chars until the next '>' */
  3912. for (p = pat + 1; p < pat_end && *p != '>'; p++)
  3913.     ;
  3914. if (p < pat_end)
  3915. {
  3916.     /* Pattern is of the form <.*>.*  */
  3917.     check_length = p - pat + 1;
  3918.     if (p + 1 >= pat_end)
  3919.     {
  3920. /* The 'pattern' is a filetype check ONLY */
  3921. reg_pat = (char_u *)alloc(check_length + 1);
  3922. if (reg_pat != NULL)
  3923. {
  3924.     mch_memmove(reg_pat, pat, check_length);
  3925.     reg_pat[check_length] = NUL;
  3926. }
  3927. return reg_pat;
  3928.     }
  3929. }
  3930. /* else: there was no closing '>' - assume it was a normal pattern */
  3931.     }
  3932.     pat += check_length;
  3933.     size = 2 + check_length;
  3934. #else
  3935.     size = 2; /* '^' at start, '$' at end */
  3936. #endif
  3937.     for (p = pat; p < pat_end; p++)
  3938.     {
  3939. switch (*p)
  3940. {
  3941.     case '*':
  3942.     case '.':
  3943.     case ',':
  3944.     case '{':
  3945.     case '}':
  3946.     case '~':
  3947. #ifdef BACKSLASH_IN_FILENAME
  3948.     case '\':
  3949. #endif
  3950. size += 2;
  3951. break;
  3952.     default:
  3953. size++;
  3954. break;
  3955. }
  3956.     }
  3957.     reg_pat = alloc(size + 1);
  3958.     if (reg_pat == NULL)
  3959. return NULL;
  3960. #ifdef WANT_FILETYPE
  3961.     /* Copy the type check in to the start. */
  3962.     if (check_length)
  3963. mch_memmove(reg_pat, pat - check_length, check_length);
  3964.     i = check_length;
  3965. #else
  3966.     i = 0;
  3967. #endif
  3968.     if (pat[0] == '*')
  3969. while (pat[0] == '*' && pat < pat_end - 1)
  3970.     pat++;
  3971.     else
  3972. reg_pat[i++] = '^';
  3973.     endp = pat_end - 1;
  3974.     if (*endp == '*')
  3975.     {
  3976. while (endp - pat > 0 && *endp == '*')
  3977.     endp--;
  3978. add_dollar = FALSE;
  3979.     }
  3980.     for (p = pat; *p && nested >= 0 && p <= endp; p++)
  3981.     {
  3982. switch (*p)
  3983. {
  3984.     case '*':
  3985. reg_pat[i++] = '.';
  3986. reg_pat[i++] = '*';
  3987. break;
  3988.     case '.':
  3989. #ifdef RISCOS
  3990. if (allow_dirs != NULL)
  3991.      *allow_dirs = TRUE;
  3992. /* FALLTHROUGH */
  3993. #endif
  3994.     case '~':
  3995. reg_pat[i++] = '\';
  3996. reg_pat[i++] = *p;
  3997. break;
  3998.     case '?':
  3999. #ifdef RISCOS
  4000.     case '#':
  4001. #endif
  4002. reg_pat[i++] = '.';
  4003. break;
  4004.     case '\':
  4005. if (p[1] == NUL)
  4006.     break;
  4007. #ifdef BACKSLASH_IN_FILENAME
  4008. /* translate "x" to "\x", "*" to "\.*", and "?" to "\." */
  4009. if (vim_isfilec(p[1]) || p[1] == '*' || p[1] == '?')
  4010. {
  4011.     reg_pat[i++] = '\';
  4012.     reg_pat[i++] = '\';
  4013.     if (allow_dirs != NULL)
  4014. *allow_dirs = TRUE;
  4015.     break;
  4016. }
  4017. ++p;
  4018. #else
  4019. if (*++p == '?')
  4020.     reg_pat[i++] = '?';
  4021. else
  4022. #endif
  4023.     if (*p == ',')
  4024. reg_pat[i++] = ',';
  4025.     else
  4026.     {
  4027. if (allow_dirs != NULL && vim_ispathsep(*p))
  4028.     *allow_dirs = TRUE;
  4029. reg_pat[i++] = '\';
  4030. reg_pat[i++] = *p;
  4031.     }
  4032. break;
  4033.     case '{':
  4034. reg_pat[i++] = '\';
  4035. reg_pat[i++] = '(';
  4036. nested++;
  4037. break;
  4038.     case '}':
  4039. reg_pat[i++] = '\';
  4040. reg_pat[i++] = ')';
  4041. --nested;
  4042. break;
  4043.     case ',':
  4044. if (nested)
  4045. {
  4046.     reg_pat[i++] = '\';
  4047.     reg_pat[i++] = '|';
  4048. }
  4049. else
  4050.     reg_pat[i++] = ',';
  4051. break;
  4052.     default:
  4053. if (allow_dirs != NULL && vim_ispathsep(*p))
  4054.     *allow_dirs = TRUE;
  4055. reg_pat[i++] = *p;
  4056. break;
  4057. }
  4058.     }
  4059.     if (add_dollar)
  4060. reg_pat[i++] = '$';
  4061.     reg_pat[i] = NUL;
  4062.     if (nested != 0)
  4063.     {
  4064. if (nested < 0)
  4065.     EMSG("Missing {.");
  4066. else
  4067.     EMSG("Missing }.");
  4068. vim_free(reg_pat);
  4069. reg_pat = NULL;
  4070.     }
  4071.     return reg_pat;
  4072. }