home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / unix / vim-6.2.tar.bz2 / vim-6.2.tar / vim62 / src / fileio.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-05-29  |  199.6 KB  |  8,190 lines

  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.  * See README.txt for an overview of the Vim source code.
  8.  */
  9.  
  10. /*
  11.  * fileio.c: read from and write to a file
  12.  */
  13.  
  14. #if defined(MSDOS) || defined(WIN16) || defined(WIN32) || defined(_WIN64)
  15. # include <io.h>    /* for lseek(), must be before vim.h */
  16. #endif
  17.  
  18. #if defined __EMX__
  19. # include <io.h>    /* for mktemp(), CJW 1997-12-03 */
  20. #endif
  21.  
  22. #include "vim.h"
  23.  
  24. #ifdef HAVE_FCNTL_H
  25. # include <fcntl.h>
  26. #endif
  27.  
  28. #ifdef LATTICE
  29. # include <proto/dos.h>        /* for Lock() and UnLock() */
  30. #endif
  31.  
  32. #ifdef __TANDEM
  33. # include <limits.h>        /* for SSIZE_MAX */
  34. #endif
  35.  
  36. #if defined(HAVE_UTIME) && defined(HAVE_UTIME_H)
  37. # include <utime.h>        /* for struct utimbuf */
  38. #endif
  39.  
  40. #define BUFSIZE        8192    /* size of normal write buffer */
  41. #define SMBUFSIZE    256    /* size of emergency write buffer */
  42.  
  43. #ifdef FEAT_CRYPT
  44. # define CRYPT_MAGIC        "VimCrypt~01!"    /* "01" is the version nr */
  45. # define CRYPT_MAGIC_LEN    12        /* must be multiple of 4! */
  46. #endif
  47.  
  48. /* Is there any system that doesn't have access()? */
  49. #ifndef MACOS_CLASSIC /* Not available on MacOS 9 */
  50. # define USE_MCH_ACCESS
  51. #endif
  52.  
  53. #ifdef FEAT_MBYTE
  54. static char_u *next_fenc __ARGS((char_u **pp));
  55. # ifdef FEAT_EVAL
  56. static char_u *readfile_charconvert __ARGS((char_u *fname, char_u *fenc, int *fdp));
  57. # endif
  58. #endif
  59. #ifdef FEAT_VIMINFO
  60. static void check_marks_read __ARGS((void));
  61. #endif
  62. #ifdef FEAT_CRYPT
  63. static char_u *check_for_cryptkey __ARGS((char_u *cryptkey, char_u *ptr, long *sizep, long *filesizep, int newfile));
  64. #endif
  65. #ifdef UNIX
  66. static void set_file_time __ARGS((char_u *fname, time_t atime, time_t mtime));
  67. #endif
  68. static void msg_add_fname __ARGS((buf_T *, char_u *));
  69. static int msg_add_fileformat __ARGS((int eol_type));
  70. static void msg_add_lines __ARGS((int, long, long));
  71. static void msg_add_eol __ARGS((void));
  72. static int check_mtime __ARGS((buf_T *buf, struct stat *s));
  73. static int time_differs __ARGS((long t1, long t2));
  74. #ifdef FEAT_AUTOCMD
  75. static int apply_autocmds_exarg __ARGS((EVENT_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf, exarg_T *eap));
  76. #endif
  77.  
  78. #if defined(FEAT_CRYPT) || defined(FEAT_MBYTE)
  79. # define HAS_BW_FLAGS
  80. # define FIO_LATIN1    0x01    /* convert Latin1 */
  81. # define FIO_UTF8    0x02    /* convert UTF-8 */
  82. # define FIO_UCS2    0x04    /* convert UCS-2 */
  83. # define FIO_UCS4    0x08    /* convert UCS-4 */
  84. # define FIO_UTF16    0x10    /* convert UTF-16 */
  85. # ifdef WIN3264
  86. #  define FIO_CODEPAGE    0x20    /* convert MS-Windows codepage */
  87. #  define FIO_PUT_CP(x) (((x) & 0xffff) << 16)    /* put codepage in top word */
  88. #  define FIO_GET_CP(x)    (((x)>>16) & 0xffff)    /* get codepage from top word */
  89. # endif
  90. # define FIO_ENDIAN_L    0x80    /* little endian */
  91. # define FIO_ENCRYPTED    0x1000    /* encrypt written bytes */
  92. # define FIO_NOCONVERT    0x2000    /* skip encoding conversion */
  93. # define FIO_UCSBOM    0x4000    /* check for BOM at start of file */
  94. # define FIO_ALL    -1    /* allow all formats */
  95. #endif
  96.  
  97. /* When converting, a read() or write() may leave some bytes to be converted
  98.  * for the next call.  The value is guessed... */
  99. #define CONV_RESTLEN 30
  100.  
  101. /* We have to guess how much a sequence of bytes may expand when converting
  102.  * with iconv() to be able to allocate a buffer. */
  103. #define ICONV_MULT 8
  104.  
  105. /*
  106.  * Structure to pass arguments from buf_write() to buf_write_bytes().
  107.  */
  108. struct bw_info
  109. {
  110.     int        bw_fd;        /* file descriptor */
  111.     char_u    *bw_buf;    /* buffer with data to be written */
  112.     int        bw_len;    /* lenght of data */
  113. #ifdef HAS_BW_FLAGS
  114.     int        bw_flags;    /* FIO_ flags */
  115. #endif
  116. #ifdef FEAT_MBYTE
  117.     char_u    bw_rest[CONV_RESTLEN]; /* not converted bytes */
  118.     int        bw_restlen;    /* nr of bytes in bw_rest[] */
  119.     int        bw_first;    /* first write call */
  120.     char_u    *bw_conv_buf;    /* buffer for writing converted chars */
  121.     int        bw_conv_buflen; /* size of bw_conv_buf */
  122.     int        bw_conv_error;    /* set for conversion error */
  123. # ifdef USE_ICONV
  124.     iconv_t    bw_iconv_fd;    /* descriptor for iconv() or -1 */
  125. # endif
  126. #endif
  127. };
  128.  
  129. static int  buf_write_bytes __ARGS((struct bw_info *ip));
  130.  
  131. #ifdef FEAT_MBYTE
  132. static int ucs2bytes __ARGS((unsigned c, char_u **pp, int flags));
  133. static int same_encoding __ARGS((char_u *a, char_u *b));
  134. static int get_fio_flags __ARGS((char_u *ptr));
  135. static char_u *check_for_bom __ARGS((char_u *p, long size, int *lenp, int flags));
  136. static int make_bom __ARGS((char_u *buf, char_u *name));
  137. # ifdef WIN3264
  138. static int get_win_fio_flags __ARGS((char_u *ptr));
  139. # endif
  140. #endif
  141. static int move_lines __ARGS((buf_T *frombuf, buf_T *tobuf));
  142.  
  143. static linenr_T    write_no_eol_lnum = 0;    /* non-zero lnum when last line of
  144.                        next binary write should not have
  145.                        an end-of-line */
  146.  
  147.     void
  148. filemess(buf, name, s, attr)
  149.     buf_T    *buf;
  150.     char_u    *name;
  151.     char_u    *s;
  152.     int        attr;
  153. {
  154.     int        msg_scroll_save;
  155.  
  156.     if (msg_silent != 0)
  157.     return;
  158.     msg_add_fname(buf, name);        /* put file name in IObuff with quotes */
  159.     /* If it's extremely long, truncate it. */
  160.     if (STRLEN(IObuff) > IOSIZE - 80)
  161.     IObuff[IOSIZE - 80] = NUL;
  162.     STRCAT(IObuff, s);
  163.     /*
  164.      * For the first message may have to start a new line.
  165.      * For further ones overwrite the previous one, reset msg_scroll before
  166.      * calling filemess().
  167.      */
  168.     msg_scroll_save = msg_scroll;
  169.     if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0)
  170.     msg_scroll = FALSE;
  171.     if (!msg_scroll)    /* wait a bit when overwriting an error msg */
  172.     check_for_delay(FALSE);
  173.     msg_start();
  174.     msg_scroll = msg_scroll_save;
  175.     msg_scrolled_ign = TRUE;
  176.     /* may truncate the message to avoid a hit-return prompt */
  177.     msg_outtrans_attr(msg_may_trunc(FALSE, IObuff), attr);
  178.     msg_clr_eos();
  179.     out_flush();
  180.     msg_scrolled_ign = FALSE;
  181. }
  182.  
  183. /*
  184.  * Read lines from file "fname" into the buffer after line "from".
  185.  *
  186.  * 1. We allocate blocks with lalloc, as big as possible.
  187.  * 2. Each block is filled with characters from the file with a single read().
  188.  * 3. The lines are inserted in the buffer with ml_append().
  189.  *
  190.  * (caller must check that fname != NULL, unless READ_STDIN is used)
  191.  *
  192.  * "lines_to_skip" is the number of lines that must be skipped
  193.  * "lines_to_read" is the number of lines that are appended
  194.  * When not recovering lines_to_skip is 0 and lines_to_read MAXLNUM.
  195.  *
  196.  * flags:
  197.  * READ_NEW    starting to edit a new buffer
  198.  * READ_FILTER    reading filter output
  199.  * READ_STDIN    read from stdin instead of a file
  200.  * READ_BUFFER    read from curbuf instead of a file (converting after reading
  201.  *        stdin)
  202.  * READ_DUMMY    read into a dummy buffer (to check if file contents changed)
  203.  *
  204.  * return FAIL for failure, OK otherwise
  205.  */
  206.     int
  207. readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
  208.     char_u    *fname;
  209.     char_u    *sfname;
  210.     linenr_T    from;
  211.     linenr_T    lines_to_skip;
  212.     linenr_T    lines_to_read;
  213.     exarg_T    *eap;            /* can be NULL! */
  214.     int        flags;
  215. {
  216.     int        fd = 0;
  217.     int        newfile = (flags & READ_NEW);
  218.     int        check_readonly;
  219.     int        filtering = (flags & READ_FILTER);
  220.     int        read_stdin = (flags & READ_STDIN);
  221.     int        read_buffer = (flags & READ_BUFFER);
  222.     linenr_T    read_buf_lnum = 1;    /* next line to read from curbuf */
  223.     colnr_T    read_buf_col = 0;    /* next char to read from this line */
  224.     char_u    c;
  225.     linenr_T    lnum = from;
  226.     char_u    *ptr = NULL;        /* pointer into read buffer */
  227.     char_u    *buffer = NULL;        /* read buffer */
  228.     char_u    *new_buffer = NULL;    /* init to shut up gcc */
  229.     char_u    *line_start = NULL;    /* init to shut up gcc */
  230.     int        wasempty;        /* buffer was empty before reading */
  231.     colnr_T    len;
  232.     long    size = 0;
  233.     char_u    *p;
  234.     long    filesize = 0;
  235.     int        skip_read = FALSE;
  236. #ifdef FEAT_CRYPT
  237.     char_u    *cryptkey = NULL;
  238. #endif
  239.     int        split = 0;        /* number of split lines */
  240. #define UNKNOWN     0x0fffffff        /* file size is unknown */
  241.     linenr_T    linecnt;
  242.     int        error = FALSE;        /* errors encountered */
  243.     int        ff_error = EOL_UNKNOWN; /* file format with errors */
  244.     long    linerest = 0;        /* remaining chars in line */
  245. #ifdef UNIX
  246.     int        perm = 0;
  247. #else
  248.     int        perm;
  249. #endif
  250.     int        fileformat = 0;        /* end-of-line format */
  251.     int        keep_fileformat = FALSE;
  252.     struct stat    st;
  253.     int        file_readonly;
  254.     linenr_T    skip_count = 0;
  255.     linenr_T    read_count = 0;
  256.     int        msg_save = msg_scroll;
  257.     linenr_T    read_no_eol_lnum = 0;   /* non-zero lnum when last line of
  258.                      * last read was missing the eol */
  259.     int        try_mac = (vim_strchr(p_ffs, 'm') != NULL);
  260.     int        try_dos = (vim_strchr(p_ffs, 'd') != NULL);
  261.     int        try_unix = (vim_strchr(p_ffs, 'x') != NULL);
  262.     int        file_rewind = FALSE;
  263. #ifdef FEAT_MBYTE
  264.     int        can_retry;
  265.     int        conv_error = FALSE;    /* conversion error detected */
  266.     linenr_T    illegal_byte = 0;    /* line nr with illegal byte */
  267.     char_u    *tmpname = NULL;    /* name of 'charconvert' output file */
  268.     int        fio_flags = 0;
  269.     char_u    *fenc;            /* fileencoding to use */
  270.     int        fenc_alloced;        /* fenc_next is in allocated memory */
  271.     char_u    *fenc_next = NULL;    /* next item in 'fencs' or NULL */
  272.     int        advance_fenc = FALSE;
  273.     long    real_size = 0;
  274. # ifdef USE_ICONV
  275.     iconv_t    iconv_fd = (iconv_t)-1;    /* descriptor for iconv() or -1 */
  276. #  ifdef FEAT_EVAL
  277.     int        did_iconv = FALSE;    /* TRUE when iconv() failed and trying
  278.                        'charconvert' next */
  279. #  endif
  280. # endif
  281.     int        converted = FALSE;    /* TRUE if conversion done */
  282.     int        notconverted = FALSE;    /* TRUE if conversion wanted but it
  283.                        wasn't possible */
  284.     char_u    conv_rest[CONV_RESTLEN];
  285.     int        conv_restlen = 0;    /* nr of bytes in conv_rest[] */
  286. #endif
  287.  
  288. #ifdef FEAT_AUTOCMD
  289.     write_no_eol_lnum = 0;    /* in case it was set by the previous read */
  290. #endif
  291.  
  292.     /*
  293.      * If there is no file name yet, use the one for the read file.
  294.      * BF_NOTEDITED is set to reflect this.
  295.      * Don't do this for a read from a filter.
  296.      * Only do this when 'cpoptions' contains the 'f' flag.
  297.      */
  298.     if (curbuf->b_ffname == NULL
  299.         && !filtering
  300.         && fname != NULL
  301.         && vim_strchr(p_cpo, CPO_FNAMER) != NULL
  302.         && !(flags & READ_DUMMY))
  303.     {
  304.     if (setfname(fname, sfname, FALSE) == OK)
  305.         curbuf->b_flags |= BF_NOTEDITED;
  306.     }
  307.  
  308.     /*
  309.      * For Unix: Use the short file name whenever possible.
  310.      * Avoids problems with networks and when directory names are changed.
  311.      * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to
  312.      * another directory, which we don't detect.
  313.      */
  314.     if (sfname == NULL)
  315.     sfname = fname;
  316. #if defined(UNIX) || defined(__EMX__)
  317.     fname = sfname;
  318. #endif
  319.  
  320. #ifdef FEAT_AUTOCMD
  321.     /*
  322.      * The BufReadCmd and FileReadCmd events intercept the reading process by
  323.      * executing the associated commands instead.
  324.      */
  325.     if (!filtering && !read_stdin && !read_buffer)
  326.     {
  327.     pos_T        pos;
  328.  
  329.     pos = curbuf->b_op_start;
  330.  
  331.     /* Set '[ mark to the line above where the lines go (line 1 if zero). */
  332.     curbuf->b_op_start.lnum = ((from == 0) ? 1 : from);
  333.     curbuf->b_op_start.col = 0;
  334.  
  335.     if (newfile)
  336.     {
  337.         if (apply_autocmds_exarg(EVENT_BUFREADCMD, NULL, sfname,
  338.                               FALSE, curbuf, eap))
  339. #ifdef FEAT_EVAL
  340.         return aborting() ? FAIL : OK;
  341. #else
  342.         return OK;
  343. #endif
  344.     }
  345.     else if (apply_autocmds_exarg(EVENT_FILEREADCMD, sfname, sfname,
  346.                                 FALSE, NULL, eap))
  347. #ifdef FEAT_EVAL
  348.         return aborting() ? FAIL : OK;
  349. #else
  350.         return OK;
  351. #endif
  352.  
  353.     curbuf->b_op_start = pos;
  354.     }
  355. #endif
  356.  
  357.     if ((shortmess(SHM_OVER) || curbuf->b_help) && p_verbose == 0)
  358.     msg_scroll = FALSE;    /* overwrite previous file message */
  359.     else
  360.     msg_scroll = TRUE;    /* don't overwrite previous file message */
  361.  
  362.     /*
  363.      * If the name ends in a path separator, we can't open it.  Check here,
  364.      * because reading the file may actually work, but then creating the swap
  365.      * file may destroy it!  Reported on MS-DOS and Win 95.
  366.      * If the name is too long we might crash further on, quit here.
  367.      */
  368.     if (fname != NULL
  369.         && *fname != NUL
  370.         && (vim_ispathsep(*(fname + STRLEN(fname) - 1))
  371.         || STRLEN(fname) >= MAXPATHL))
  372.     {
  373.     filemess(curbuf, fname, (char_u *)_("Illegal file name"), 0);
  374.     msg_end();
  375.     msg_scroll = msg_save;
  376.     return FAIL;
  377.     }
  378.  
  379. #ifdef UNIX
  380.     /*
  381.      * On Unix it is possible to read a directory, so we have to
  382.      * check for it before the mch_open().
  383.      */
  384.     if (!read_stdin && !read_buffer)
  385.     {
  386.     perm = mch_getperm(fname);
  387.     if (perm >= 0 && !S_ISREG(perm)            /* not a regular file ... */
  388. # ifdef S_ISFIFO
  389.               && !S_ISFIFO(perm)        /* ... or fifo */
  390. # endif
  391. # ifdef S_ISSOCK
  392.               && !S_ISSOCK(perm)        /* ... or socket */
  393. # endif
  394.                         )
  395.     {
  396.         if (S_ISDIR(perm))
  397.         filemess(curbuf, fname, (char_u *)_("is a directory"), 0);
  398.         else
  399.         filemess(curbuf, fname, (char_u *)_("is not a file"), 0);
  400.         msg_end();
  401.         msg_scroll = msg_save;
  402.         return FAIL;
  403.     }
  404.     }
  405. #endif
  406.  
  407.     /* set default 'fileformat' */
  408.     if (newfile)
  409.     {
  410.     if (eap != NULL && eap->force_ff != 0)
  411.         set_fileformat(get_fileformat_force(curbuf, eap), OPT_LOCAL);
  412.     else if (*p_ffs != NUL)
  413.         set_fileformat(default_fileformat(), OPT_LOCAL);
  414.     }
  415.  
  416.     /*
  417.      * When opening a new file we take the readonly flag from the file.
  418.      * Default is r/w, can be set to r/o below.
  419.      * Don't reset it when in readonly mode
  420.      * Only set/reset b_p_ro when BF_CHECK_RO is set.
  421.      */
  422.     check_readonly = (newfile && (curbuf->b_flags & BF_CHECK_RO));
  423.     if (check_readonly && !readonlymode)    /* default: set file not readonly */
  424.     curbuf->b_p_ro = FALSE;
  425.  
  426.     if (newfile && !read_stdin && !read_buffer)
  427.     {
  428.     /* Remember time of file.
  429.      * For RISCOS, also remember the filetype.
  430.      */
  431.     if (mch_stat((char *)fname, &st) >= 0)
  432.     {
  433.         buf_store_time(curbuf, &st, fname);
  434.         curbuf->b_mtime_read = curbuf->b_mtime;
  435.  
  436. #if defined(RISCOS) && defined(FEAT_OSFILETYPE)
  437.         /* Read the filetype into the buffer local filetype option. */
  438.         mch_read_filetype(fname);
  439. #endif
  440. #ifdef UNIX
  441.         /*
  442.          * Set the protection bits of the swap file equal to the original
  443.          * file. This makes it possible for others to read the name of the
  444.          * original file from the swapfile.
  445.          */
  446.         if (curbuf->b_ml.ml_mfp->mf_fname != NULL)
  447.         (void)mch_setperm(curbuf->b_ml.ml_mfp->mf_fname,
  448.                       (long)((st.st_mode & 0777) | 0600));
  449. #endif
  450. #ifdef MACOS_CLASSIC /* TODO: Is it need for MACOS_X? (Dany) */
  451.         /* Get the FSSpec on MacOS
  452.          * TODO: Update it properly when the buffer name changes
  453.          */
  454.         (void)GetFSSpecFromPath(curbuf->b_ffname, &curbuf->b_FSSpec);
  455. #endif
  456. #ifdef VMS
  457.         curbuf->b_fab_rfm = st.st_fab_rfm;
  458. #endif
  459.     }
  460.     else
  461.     {
  462.         curbuf->b_mtime = 0;
  463.         curbuf->b_mtime_read = 0;
  464.         curbuf->b_orig_size = 0;
  465.         curbuf->b_orig_mode = 0;
  466.     }
  467.  
  468.     /* Reset the "new file" flag.  It will be set again below when the
  469.      * file doesn't exist. */
  470.     curbuf->b_flags &= ~(BF_NEW | BF_NEW_W);
  471.     }
  472.  
  473. /*
  474.  * for UNIX: check readonly with perm and mch_access()
  475.  * for RISCOS: same as Unix, otherwise file gets re-datestamped!
  476.  * for MSDOS and Amiga: check readonly by trying to open the file for writing
  477.  */
  478.     file_readonly = FALSE;
  479.     if (read_stdin)
  480.     {
  481. #if defined(MSDOS) || defined(MSWIN) || defined(OS2)
  482.     /* Force binary I/O on stdin to avoid CR-LF -> LF conversion. */
  483.     setmode(0, O_BINARY);
  484. #endif
  485.     }
  486.     else if (!read_buffer)
  487.     {
  488. #ifdef USE_MCH_ACCESS
  489.     if (
  490. # ifdef UNIX
  491.         !(perm & 0222) ||
  492. # endif
  493.                 mch_access((char *)fname, W_OK))
  494.         file_readonly = TRUE;
  495.     fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
  496. #else
  497.     if (!newfile
  498.         || readonlymode
  499.         || (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0)
  500.     {
  501.         file_readonly = TRUE;
  502.         /* try to open ro */
  503.         fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
  504.     }
  505. #endif
  506.     }
  507.  
  508.     if (fd < 0)                /* cannot open at all */
  509.     {
  510. #ifndef UNIX
  511.     int    isdir_f;
  512. #endif
  513.     msg_scroll = msg_save;
  514. #ifndef UNIX
  515.     /*
  516.      * On MSDOS and Amiga we can't open a directory, check here.
  517.      */
  518.     isdir_f = (mch_isdir(fname));
  519.     perm = mch_getperm(fname);  /* check if the file exists */
  520.     if (isdir_f)
  521.     {
  522.         filemess(curbuf, sfname, (char_u *)_("is a directory"), 0);
  523.         curbuf->b_p_ro = TRUE;    /* must use "w!" now */
  524.     }
  525.     else
  526. #endif
  527.         if (newfile)
  528.         {
  529.         if (perm < 0)
  530.         {
  531.             /*
  532.              * Set the 'new-file' flag, so that when the file has
  533.              * been created by someone else, a ":w" will complain.
  534.              */
  535.             curbuf->b_flags |= BF_NEW;
  536.  
  537.             /* Create a swap file now, so that other Vims are warned
  538.              * that we are editing this file.  Don't do this for a
  539.              * "nofile" or "nowrite" buffer type. */
  540. #ifdef FEAT_QUICKFIX
  541.             if (!bt_dontwrite(curbuf))
  542. #endif
  543.             check_need_swap(newfile);
  544.             filemess(curbuf, sfname, (char_u *)_("[New File]"), 0);
  545. #ifdef FEAT_VIMINFO
  546.             /* Even though this is a new file, it might have been
  547.              * edited before and deleted.  Get the old marks. */
  548.             check_marks_read();
  549. #endif
  550. #ifdef FEAT_AUTOCMD
  551.             apply_autocmds_exarg(EVENT_BUFNEWFILE, sfname, sfname,
  552.                               FALSE, curbuf, eap);
  553. #endif
  554.             /* remember the current fileformat */
  555.             save_file_ff(curbuf);
  556.  
  557. #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  558.             if (aborting())   /* autocmds may abort script processing */
  559.             return FAIL;
  560. #endif
  561.             return OK;        /* a new file is not an error */
  562.         }
  563.         else
  564.         {
  565.             filemess(curbuf, sfname,
  566.                        (char_u *)_("[Permission Denied]"), 0);
  567.             curbuf->b_p_ro = TRUE;    /* must use "w!" now */
  568.         }
  569.         }
  570.  
  571.     return FAIL;
  572.     }
  573.  
  574.     /*
  575.      * Only set the 'ro' flag for readonly files the first time they are
  576.      * loaded.    Help files always get readonly mode
  577.      */
  578.     if ((check_readonly && file_readonly) || curbuf->b_help)
  579.     curbuf->b_p_ro = TRUE;
  580.  
  581.     if (newfile)
  582.     {
  583.     curbuf->b_p_eol = TRUE;
  584.     curbuf->b_start_eol = TRUE;
  585. #ifdef FEAT_MBYTE
  586.     curbuf->b_p_bomb = FALSE;
  587. #endif
  588.     }
  589.  
  590.     /* Create a swap file now, so that other Vims are warned that we are
  591.      * editing this file.
  592.      * Don't do this for a "nofile" or "nowrite" buffer type. */
  593. #ifdef FEAT_QUICKFIX
  594.     if (!bt_dontwrite(curbuf))
  595. #endif
  596.     check_need_swap(newfile);
  597.  
  598. #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  599.     /* If "Quit" selected at ATTENTION dialog, don't load the file */
  600.     if (swap_exists_action == SEA_QUIT)
  601.     {
  602.     if (!read_buffer && !read_stdin)
  603.         close(fd);
  604.     return FAIL;
  605.     }
  606. #endif
  607.  
  608.     ++no_wait_return;        /* don't wait for return yet */
  609.  
  610.     /*
  611.      * Set '[ mark to the line above where the lines go (line 1 if zero).
  612.      */
  613.     curbuf->b_op_start.lnum = ((from == 0) ? 1 : from);
  614.     curbuf->b_op_start.col = 0;
  615.  
  616. #ifdef FEAT_AUTOCMD
  617.     if (!read_buffer)
  618.     {
  619.     int    m = msg_scroll;
  620.     int    n = msg_scrolled;
  621.     buf_T    *old_curbuf = curbuf;
  622.  
  623.     /*
  624.      * The file must be closed again, the autocommands may want to change
  625.      * the file before reading it.
  626.      */
  627.     if (!read_stdin)
  628.         close(fd);        /* ignore errors */
  629.  
  630.     /*
  631.      * The output from the autocommands should not overwrite anything and
  632.      * should not be overwritten: Set msg_scroll, restore its value if no
  633.      * output was done.
  634.      */
  635.     msg_scroll = TRUE;
  636.     if (filtering)
  637.         apply_autocmds_exarg(EVENT_FILTERREADPRE, NULL, sfname,
  638.                               FALSE, curbuf, eap);
  639.     else if (read_stdin)
  640.         apply_autocmds_exarg(EVENT_STDINREADPRE, NULL, sfname,
  641.                               FALSE, curbuf, eap);
  642.     else if (newfile)
  643.         apply_autocmds_exarg(EVENT_BUFREADPRE, NULL, sfname,
  644.                               FALSE, curbuf, eap);
  645.     else
  646.         apply_autocmds_exarg(EVENT_FILEREADPRE, sfname, sfname,
  647.                                 FALSE, NULL, eap);
  648.     if (msg_scrolled == n)
  649.         msg_scroll = m;
  650.  
  651. #ifdef FEAT_EVAL
  652.     if (aborting())        /* autocmds may abort script processing */
  653.     {
  654.         --no_wait_return;
  655.         msg_scroll = msg_save;
  656.         curbuf->b_p_ro = TRUE;    /* must use "w!" now */
  657.         return FAIL;
  658.     }
  659. #endif
  660.     /*
  661.      * Don't allow the autocommands to change the current buffer.
  662.      * Try to re-open the file.
  663.      */
  664.     if (!read_stdin && (curbuf != old_curbuf
  665.         || (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) < 0))
  666.     {
  667.         --no_wait_return;
  668.         msg_scroll = msg_save;
  669.         if (fd < 0)
  670.         EMSG(_("E200: *ReadPre autocommands made the file unreadable"));
  671.         else
  672.         EMSG(_("E201: *ReadPre autocommands must not change current buffer"));
  673.         curbuf->b_p_ro = TRUE;    /* must use "w!" now */
  674.         return FAIL;
  675.     }
  676.     }
  677. #endif /* FEAT_AUTOCMD */
  678.  
  679.     /* Autocommands may add lines to the file, need to check if it is empty */
  680.     wasempty = (curbuf->b_ml.ml_flags & ML_EMPTY);
  681.  
  682.     if (!recoverymode && !filtering && !(flags & READ_DUMMY))
  683.     {
  684.     /*
  685.      * Show the user that we are busy reading the input.  Sometimes this
  686.      * may take a while.  When reading from stdin another program may
  687.      * still be running, don't move the cursor to the last line, unless
  688.      * always using the GUI.
  689.      */
  690.     if (read_stdin)
  691.     {
  692. #ifndef ALWAYS_USE_GUI
  693.         mch_msg(_("Vim: Reading from stdin...\n"));
  694. #endif
  695. #ifdef FEAT_GUI
  696.         /* Also write a message in the GUI window, if there is one. */
  697.         if (gui.in_use && !gui.dying && !gui.starting)
  698.         {
  699.         p = (char_u *)_("Reading from stdin...");
  700.         gui_write(p, (int)STRLEN(p));
  701.         }
  702. #endif
  703.     }
  704.     else if (!read_buffer)
  705.         filemess(curbuf, sfname, (char_u *)"", 0);
  706.     }
  707.  
  708.     msg_scroll = FALSE;            /* overwrite the file message */
  709.  
  710.     /*
  711.      * Set linecnt now, before the "retry" caused by a wrong guess for
  712.      * fileformat, and after the autocommands, which may change them.
  713.      */
  714.     linecnt = curbuf->b_ml.ml_line_count;
  715.  
  716. #ifdef FEAT_MBYTE
  717.     /*
  718.      * Decide which 'encoding' to use first.
  719.      */
  720.     if (eap != NULL && eap->force_enc != 0)
  721.     {
  722.     fenc = enc_canonize(eap->cmd + eap->force_enc);
  723.     fenc_alloced = TRUE;
  724.     }
  725.     else if (curbuf->b_p_bin)
  726.     {
  727.     fenc = (char_u *)"";        /* binary: don't convert */
  728.     fenc_alloced = FALSE;
  729.     }
  730.     else if (curbuf->b_help)
  731.     {
  732.     /* Help files are either utf-8 or latin1.  Try utf-8 first, if this
  733.      * fails it must be latin1.  Only do this when 'encoding' is utf-8 to
  734.      * avoid [converted] remarks all the time. */
  735.     fenc = (char_u *)"latin1";
  736.     if (enc_utf8)
  737.     {
  738.         fenc_next = fenc;
  739.         fenc = (char_u *)"utf-8";
  740.     }
  741.     fenc_alloced = FALSE;
  742.     }
  743.     else if (*p_fencs == NUL)
  744.     {
  745.     fenc = curbuf->b_p_fenc;    /* use format from buffer */
  746.     fenc_alloced = FALSE;
  747.     }
  748.     else
  749.     {
  750.     fenc_next = p_fencs;        /* try items in 'fileencodings' */
  751.     fenc = next_fenc(&fenc_next);
  752.     fenc_alloced = TRUE;
  753.     }
  754. #endif
  755.  
  756.     /*
  757.      * Jump back here to retry reading the file in different ways.
  758.      * Reasons to retry:
  759.      * - encoding conversion failed: try another one from "fenc_next"
  760.      * - BOM detected and fenc was set, need to setup conversion
  761.      * - "fileformat" check failed: try another
  762.      *
  763.      * Variables set for special retry actions:
  764.      * "file_rewind"    Rewind the file to start reading it again.
  765.      * "advance_fenc"    Advance "fenc" using "fenc_next".
  766.      * "skip_read"    Re-use already read bytes (BOM detected).
  767.      * "did_iconv"    iconv() conversion failed, try 'charconvert'.
  768.      * "keep_fileformat" Don't reset "fileformat".
  769.      *
  770.      * Other status indicators:
  771.      * "tmpname"    When != NULL did conversion with 'charconvert'.
  772.      *            Output file has to be deleted afterwards.
  773.      * "iconv_fd"    When != -1 did conversion with iconv().
  774.      */
  775. retry:
  776.  
  777.     if (file_rewind)
  778.     {
  779.     if (read_buffer)
  780.     {
  781.         read_buf_lnum = 1;
  782.         read_buf_col = 0;
  783.     }
  784.     else if (read_stdin || lseek(fd, (off_t)0L, SEEK_SET) != 0)
  785.     {
  786.         /* Can't rewind the file, give up. */
  787.         error = TRUE;
  788.         goto failed;
  789.     }
  790.     /* Delete the previously read lines. */
  791.     while (lnum > from)
  792.         ml_delete(lnum--, FALSE);
  793.     file_rewind = FALSE;
  794. #ifdef FEAT_MBYTE
  795.     if (newfile)
  796.         curbuf->b_p_bomb = FALSE;
  797.     conv_error = FALSE;
  798. #endif
  799.     }
  800.  
  801.     /*
  802.      * When retrying with another "fenc" and the first time "fileformat"
  803.      * will be reset.
  804.      */
  805.     if (keep_fileformat)
  806.     keep_fileformat = FALSE;
  807.     else
  808.     {
  809.     if (eap != NULL && eap->force_ff != 0)
  810.         fileformat = get_fileformat_force(curbuf, eap);
  811.     else if (curbuf->b_p_bin)
  812.         fileformat = EOL_UNIX;        /* binary: use Unix format */
  813.     else if (*p_ffs == NUL)
  814.         fileformat = get_fileformat(curbuf);/* use format from buffer */
  815.     else
  816.         fileformat = EOL_UNKNOWN;        /* detect from file */
  817.     }
  818.  
  819. #ifdef FEAT_MBYTE
  820. # ifdef USE_ICONV
  821.     if (iconv_fd != (iconv_t)-1)
  822.     {
  823.     /* aborted conversion with iconv(), close the descriptor */
  824.     iconv_close(iconv_fd);
  825.     iconv_fd = (iconv_t)-1;
  826.     }
  827. # endif
  828.  
  829.     if (advance_fenc)
  830.     {
  831.     /*
  832.      * Try the next entry in 'fileencodings'.
  833.      */
  834.     advance_fenc = FALSE;
  835.  
  836.     if (eap != NULL && eap->force_enc != 0)
  837.     {
  838.         /* Conversion given with "++cc=" wasn't possible, read
  839.          * without conversion. */
  840.         notconverted = TRUE;
  841.         conv_error = FALSE;
  842.         if (fenc_alloced)
  843.         vim_free(fenc);
  844.         fenc = (char_u *)"";
  845.         fenc_alloced = FALSE;
  846.     }
  847.     else
  848.     {
  849.         if (fenc_alloced)
  850.         vim_free(fenc);
  851.         if (fenc_next != NULL)
  852.         {
  853.         fenc = next_fenc(&fenc_next);
  854.         fenc_alloced = (fenc_next != NULL);
  855.         }
  856.         else
  857.         {
  858.         fenc = (char_u *)"";
  859.         fenc_alloced = FALSE;
  860.         }
  861.     }
  862.     if (tmpname != NULL)
  863.     {
  864.         mch_remove(tmpname);        /* delete converted file */
  865.         vim_free(tmpname);
  866.         tmpname = NULL;
  867.     }
  868.     }
  869.  
  870.     /*
  871.      * Conversion is required when the encoding of the file is different
  872.      * from 'encoding' or 'encoding' is UTF-16, UCS-2 or UCS-4 (requires
  873.      * conversion to UTF-8).
  874.      */
  875.     fio_flags = 0;
  876.     converted = (*fenc != NUL && !same_encoding(p_enc, fenc));
  877.     if (converted || enc_unicode != 0)
  878.     {
  879.  
  880.     /* "ucs-bom" means we need to check the first bytes of the file
  881.      * for a BOM. */
  882.     if (STRCMP(fenc, ENC_UCSBOM) == 0)
  883.         fio_flags = FIO_UCSBOM;
  884.  
  885.     /*
  886.      * Check if UCS-2/4 or Latin1 to UTF-8 conversion needs to be
  887.      * done.  This is handled below after read().  Prepare the
  888.      * fio_flags to avoid having to parse the string each time.
  889.      * Also check for Unicode to Latin1 conversion, because iconv()
  890.      * appears not to handle this correctly.  This works just like
  891.      * conversion to UTF-8 except how the resulting character is put in
  892.      * the buffer.
  893.      */
  894.     else if (enc_utf8 || STRCMP(p_enc, "latin1") == 0)
  895.         fio_flags = get_fio_flags(fenc);
  896.  
  897. # ifdef WIN3264
  898.     /*
  899.      * Conversion from an MS-Windows codepage to UTF-8 is handled here.
  900.      */
  901.     if (fio_flags == 0 && enc_utf8)
  902.         fio_flags = get_win_fio_flags(fenc);
  903. # endif
  904.  
  905. # ifdef USE_ICONV
  906.     /*
  907.      * Try using iconv() if we can't convert internally.
  908.      */
  909.     if (fio_flags == 0
  910. #  ifdef FEAT_EVAL
  911.         && !did_iconv
  912. #  endif
  913.         )
  914.         iconv_fd = (iconv_t)my_iconv_open(
  915.                   enc_utf8 ? (char_u *)"utf-8" : p_enc, fenc);
  916. # endif
  917.  
  918. # ifdef FEAT_EVAL
  919.     /*
  920.      * Use the 'charconvert' expression when conversion is required
  921.      * and we can't do it internally or with iconv().
  922.      */
  923.     if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL
  924. #  ifdef USE_ICONV
  925.                             && iconv_fd == (iconv_t)-1
  926. #  endif
  927.         )
  928.     {
  929. #  ifdef USE_ICONV
  930.         did_iconv = FALSE;
  931. #  endif
  932.         /* Skip conversion when it's already done (retry for wrong
  933.          * "fileformat"). */
  934.         if (tmpname == NULL)
  935.         {
  936.         tmpname = readfile_charconvert(fname, fenc, &fd);
  937.         if (tmpname == NULL)
  938.         {
  939.             /* Conversion failed.  Try another one. */
  940.             advance_fenc = TRUE;
  941.             if (fd < 0)
  942.             {
  943.             /* Re-opening the original file failed! */
  944.             EMSG(_("E202: Conversion made file unreadable!"));
  945.             error = TRUE;
  946.             goto failed;
  947.             }
  948.             goto retry;
  949.         }
  950.         }
  951.     }
  952.     else
  953. # endif
  954.     {
  955.         if (fio_flags == 0
  956. # ifdef USE_ICONV
  957.             && iconv_fd == (iconv_t)-1
  958. # endif
  959.            )
  960.         {
  961.         /* Conversion wanted but we can't.
  962.          * Try the next conversion in 'fileencodings' */
  963.         advance_fenc = TRUE;
  964.         goto retry;
  965.         }
  966.     }
  967.     }
  968.  
  969.     /* Set can_retry when it's possible to rewind the file and try with
  970.      * another "fenc" value.  It's FALSE when no other "fenc" to try, reading
  971.      * stdin or "fenc" was specified with "++enc=". */
  972.     can_retry = (*fenc != NUL && !read_stdin
  973.                      && (eap == NULL || eap->force_enc == 0));
  974. #endif
  975.  
  976.     if (!skip_read)
  977.     {
  978.     linerest = 0;
  979.     filesize = 0;
  980.     skip_count = lines_to_skip;
  981.     read_count = lines_to_read;
  982. #ifdef FEAT_MBYTE
  983.     conv_restlen = 0;
  984. #endif
  985.     }
  986.  
  987.     while (!error && !got_int)
  988.     {
  989.     /*
  990.      * We allocate as much space for the file as we can get, plus
  991.      * space for the old line plus room for one terminating NUL.
  992.      * The amount is limited by the fact that read() only can read
  993.      * upto max_unsigned characters (and other things).
  994.      */
  995. #if SIZEOF_INT <= 2
  996.     if (linerest >= 0x7ff0)
  997.     {
  998.         ++split;
  999.         *ptr = NL;            /* split line by inserting a NL */
  1000.         size = 1;
  1001.     }
  1002.     else
  1003. #endif
  1004.     {
  1005.         if (!skip_read)
  1006.         {
  1007. #if SIZEOF_INT > 2
  1008. # ifdef __TANDEM
  1009.         size = SSIZE_MAX;            /* use max I/O size, 52K */
  1010. # else
  1011.         size = 0x10000L;            /* use buffer >= 64K */
  1012. # endif
  1013. #else
  1014.         size = 0x7ff0L - linerest;        /* limit buffer to 32K */
  1015. #endif
  1016.  
  1017.         for ( ; size >= 10; size = (long_u)size >> 1)
  1018.         {
  1019.             if ((new_buffer = lalloc((long_u)(size + linerest + 1),
  1020.                                   FALSE)) != NULL)
  1021.             break;
  1022.         }
  1023.         if (new_buffer == NULL)
  1024.         {
  1025.             do_outofmem_msg((long_u)(size * 2 + linerest + 1));
  1026.             error = TRUE;
  1027.             break;
  1028.         }
  1029.         if (linerest)    /* copy characters from the previous buffer */
  1030.             mch_memmove(new_buffer, ptr - linerest, (size_t)linerest);
  1031.         vim_free(buffer);
  1032.         buffer = new_buffer;
  1033.         ptr = buffer + linerest;
  1034.         line_start = buffer;
  1035.  
  1036. #ifdef FEAT_MBYTE
  1037.         /* May need room to translate into.
  1038.          * For iconv() we don't really know the required space, use a
  1039.          * factor ICONV_MULT.
  1040.          * latin1 to utf-8: 1 byte becomes up to 2 bytes
  1041.          * utf-16 to utf-8: 2 bytes become up to 3 bytes, 4 bytes
  1042.          * become up to 4 bytes, size must be multiple of 2
  1043.          * ucs-2 to utf-8: 2 bytes become up to 3 bytes, size must be
  1044.          * multiple of 2
  1045.          * ucs-4 to utf-8: 4 bytes become up to 6 bytes, size must be
  1046.          * multiple of 4 */
  1047.         real_size = size;
  1048. # ifdef USE_ICONV
  1049.         if (iconv_fd != (iconv_t)-1)
  1050.             size = size / ICONV_MULT;
  1051.         else
  1052. # endif
  1053.             if (fio_flags & FIO_LATIN1)
  1054.             size = size / 2;
  1055.         else if (fio_flags & (FIO_UCS2 | FIO_UTF16))
  1056.             size = (size * 2 / 3) & ~1;
  1057.         else if (fio_flags & FIO_UCS4)
  1058.             size = (size * 2 / 3) & ~3;
  1059.         else if (fio_flags == FIO_UCSBOM)
  1060.             size = size / ICONV_MULT;    /* worst case */
  1061. # ifdef WIN3264
  1062.         else if (fio_flags & FIO_CODEPAGE)
  1063.             size = size / ICONV_MULT;    /* also worst case */
  1064. # endif
  1065. #endif
  1066.  
  1067. #ifdef FEAT_MBYTE
  1068.         if (conv_restlen > 0)
  1069.         {
  1070.             /* Insert unconverted bytes from previous line. */
  1071.             mch_memmove(ptr, conv_rest, conv_restlen);
  1072.             ptr += conv_restlen;
  1073.             size -= conv_restlen;
  1074.         }
  1075. #endif
  1076.  
  1077.         if (read_buffer)
  1078.         {
  1079.             /*
  1080.              * Read bytes from curbuf.  Used for converting text read
  1081.              * from stdin.
  1082.              */
  1083.             if (read_buf_lnum > from)
  1084.             size = 0;
  1085.             else
  1086.             {
  1087.             int    n;
  1088.             long    tlen;
  1089.  
  1090.             tlen = 0;
  1091.             for (;;)
  1092.             {
  1093.                 p = ml_get(read_buf_lnum) + read_buf_col;
  1094.                 n = (int)STRLEN(p);
  1095.                 if ((int)tlen + n + 1 > size)
  1096.                 {
  1097.                 /* Filled up to "size", append partial line. */
  1098.                 n = size - tlen;
  1099.                 mch_memmove(ptr + tlen, p, (size_t)n);
  1100.                 read_buf_col += n;
  1101.                 break;
  1102.                 }
  1103.                 else
  1104.                 {
  1105.                 /* Append whole line and new-line. */
  1106.                 mch_memmove(ptr + tlen, p, (size_t)n);
  1107.                 tlen += n;
  1108.                 ptr[tlen++] = NL;
  1109.                 read_buf_col = 0;
  1110.                 if (++read_buf_lnum > from)
  1111.                 {
  1112.                     /* When the last line didn't have an
  1113.                      * end-of-line don't add it now either. */
  1114.                     if (!curbuf->b_p_eol)
  1115.                     --tlen;
  1116.                     size = tlen;
  1117.                     break;
  1118.                 }
  1119.                 }
  1120.             }
  1121.             }
  1122.         }
  1123.         else
  1124.         {
  1125.             /*
  1126.              * Read bytes from the file.
  1127.              */
  1128.             size = vim_read(fd, ptr, size);
  1129.         }
  1130.  
  1131.         if (size <= 0)
  1132.         {
  1133.             if (size < 0)            /* read error */
  1134.             error = TRUE;
  1135. #ifdef FEAT_MBYTE
  1136.             else if (conv_restlen > 0)
  1137.             /* some trailing bytes unconverted */
  1138.             conv_error = TRUE;
  1139. #endif
  1140.         }
  1141.  
  1142. #ifdef FEAT_CRYPT
  1143.         /*
  1144.          * At start of file: Check for magic number of encryption.
  1145.          */
  1146.         if (filesize == 0)
  1147.             cryptkey = check_for_cryptkey(cryptkey, ptr, &size,
  1148.                               &filesize, newfile);
  1149.         /*
  1150.          * Decrypt the read bytes.
  1151.          */
  1152.         if (cryptkey != NULL && size > 0)
  1153.             for (p = ptr; p < ptr + size; ++p)
  1154.             ZDECODE(*p);
  1155. #endif
  1156.         }
  1157.         skip_read = FALSE;
  1158.  
  1159. #ifdef FEAT_MBYTE
  1160.         /*
  1161.          * At start of file (or after crypt magic number): Check for BOM.
  1162.          * Also check for a BOM for other Unicode encodings, but not after
  1163.          * converting with 'charconvert' or when a BOM has already been
  1164.          * found.
  1165.          */
  1166.         if ((filesize == 0
  1167. # ifdef FEAT_CRYPT
  1168.             || (filesize == CRYPT_MAGIC_LEN && cryptkey != NULL)
  1169. # endif
  1170.                )
  1171.             && (fio_flags == FIO_UCSBOM
  1172.             || (!curbuf->b_p_bomb
  1173.                 && tmpname == NULL
  1174.                 && (*fenc == 'u' || (*fenc == NUL && enc_utf8)))))
  1175.         {
  1176.         char_u    *ccname;
  1177.         int    blen;
  1178.  
  1179.         /* no BOM detection in a short file or in binary mode */
  1180.         if (size < 2 || curbuf->b_p_bin)
  1181.             ccname = NULL;
  1182.         else
  1183.             ccname = check_for_bom(ptr, size, &blen,
  1184.               fio_flags == FIO_UCSBOM ? FIO_ALL : get_fio_flags(fenc));
  1185.         if (ccname != NULL)
  1186.         {
  1187.             /* Remove BOM from the text */
  1188.             filesize += blen;
  1189.             size -= blen;
  1190.             mch_memmove(ptr, ptr + blen, (size_t)size);
  1191.             if (newfile)
  1192.             curbuf->b_p_bomb = TRUE;
  1193.         }
  1194.  
  1195.         if (fio_flags == FIO_UCSBOM)
  1196.         {
  1197.             if (ccname == NULL)
  1198.             {
  1199.             /* No BOM detected: retry with next encoding. */
  1200.             advance_fenc = TRUE;
  1201.             }
  1202.             else
  1203.             {
  1204.             /* BOM detected: set "fenc" and jump back */
  1205.             if (fenc_alloced)
  1206.                 vim_free(fenc);
  1207.             fenc = ccname;
  1208.             fenc_alloced = FALSE;
  1209.             }
  1210.             /* retry reading without getting new bytes or rewinding */
  1211.             skip_read = TRUE;
  1212.             goto retry;
  1213.         }
  1214.         }
  1215. #endif
  1216.         /*
  1217.          * Break here for a read error or end-of-file.
  1218.          */
  1219.         if (size <= 0)
  1220.         break;
  1221.  
  1222. #ifdef FEAT_MBYTE
  1223.  
  1224.         /* Include not converted bytes. */
  1225.         ptr -= conv_restlen;
  1226.         size += conv_restlen;
  1227.         conv_restlen = 0;
  1228.  
  1229. # ifdef USE_ICONV
  1230.         if (iconv_fd != (iconv_t)-1)
  1231.         {
  1232.         /*
  1233.          * Attempt conversion of the read bytes to 'encoding' using
  1234.          * iconv().
  1235.          */
  1236.         const char    *fromp;
  1237.         char        *top;
  1238.         size_t        from_size;
  1239.         size_t        to_size;
  1240.  
  1241.         fromp = (char *)ptr;
  1242.         from_size = size;
  1243.         ptr += size;
  1244.         top = (char *)ptr;
  1245.         to_size = real_size - size;
  1246.  
  1247.         /*
  1248.          * If there is conversion error or not enough room try using
  1249.          * another conversion.
  1250.          */
  1251.         if ((iconv(iconv_fd, &fromp, &from_size, &top, &to_size)
  1252.                 == (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL)
  1253.                           || from_size > CONV_RESTLEN)
  1254.             goto rewind_retry;
  1255.  
  1256.         if (from_size > 0)
  1257.         {
  1258.             /* Some remaining characters, keep them for the next
  1259.              * round. */
  1260.             mch_memmove(conv_rest, (char_u *)fromp, from_size);
  1261.             conv_restlen = (int)from_size;
  1262.         }
  1263.  
  1264.         /* move the linerest to before the converted characters */
  1265.         line_start = ptr - linerest;
  1266.         mch_memmove(line_start, buffer, (size_t)linerest);
  1267.         size = (long)((char_u *)top - ptr);
  1268.         }
  1269. # endif
  1270.  
  1271. # ifdef WIN3264
  1272.         if (fio_flags & FIO_CODEPAGE)
  1273.         {
  1274.         /*
  1275.          * Conversion from an MS-Windows codepage to UTF-8, using
  1276.          * standard MS-Windows functions.
  1277.          */
  1278.         char_u    *ucsp;
  1279.         size_t    from_size;
  1280.         int    needed;
  1281.         char_u    *p;
  1282.         int    u8c;
  1283.  
  1284.         /*
  1285.          * We can't tell if the last byte of an MBCS string is valid
  1286.          * and MultiByteToWideChar() returns zero if it isn't.
  1287.          * Try the whole string, and if that fails, bump the last byte
  1288.          * into conv_rest and try again.
  1289.          */
  1290.         from_size = size;
  1291.         needed = MultiByteToWideChar(FIO_GET_CP(fio_flags),
  1292.                    MB_ERR_INVALID_CHARS, (LPCSTR)ptr, from_size,
  1293.                                      NULL, 0);
  1294.         if (needed == 0)
  1295.         {
  1296.             conv_rest[0] = ptr[from_size - 1];
  1297.             conv_restlen = 1;
  1298.             --from_size;
  1299.             needed = MultiByteToWideChar(FIO_GET_CP(fio_flags),
  1300.                    MB_ERR_INVALID_CHARS, (LPCSTR)ptr, from_size,
  1301.                                      NULL, 0);
  1302.         }
  1303.  
  1304.         /* If there really is a conversion error, try using another
  1305.          * conversion. */
  1306.         if (needed == 0)
  1307.             goto rewind_retry;
  1308.  
  1309.         /* Put the result of conversion to UCS-2 at the end of the
  1310.          * buffer, then convert from UCS-2 to UTF-8 into the start of
  1311.          * the buffer.  If there is not enough space just fail, there
  1312.          * is probably something wrong. */
  1313.         ucsp = ptr + real_size - (needed * sizeof(WCHAR));
  1314.         if (ucsp < ptr + size)
  1315.             goto rewind_retry;
  1316.         needed = MultiByteToWideChar(FIO_GET_CP(fio_flags),
  1317.                         MB_ERR_INVALID_CHARS, (LPCSTR)ptr,
  1318.                          from_size, (LPWSTR)ucsp, needed);
  1319.  
  1320.         /* Now go from UCS-2 to UTF-8. */
  1321.         p = ptr;
  1322.         for (; needed > 0; --needed)
  1323.         {
  1324.             u8c = *ucsp++;
  1325.             u8c += (*ucsp++ << 8);
  1326.             p += utf_char2bytes(u8c, p);
  1327.         }
  1328.         size = p - ptr;
  1329.         }
  1330.         else
  1331. # endif
  1332.         if (fio_flags != 0)
  1333.         {
  1334.         int    u8c;
  1335.         char_u    *dest;
  1336.         char_u    *tail = NULL;
  1337.  
  1338.         /*
  1339.          * "enc_utf8" set: Convert Unicode or Latin1 to UTF-8.
  1340.          * "enc_utf8" not set: Convert Unicode to Latin1.
  1341.          * Go from end to start through the buffer, because the number
  1342.          * of bytes may increase.
  1343.          * "dest" points to after where the UTF-8 bytes go, "p" points
  1344.          * to after the next character to convert.
  1345.          */
  1346.         dest = ptr + real_size;
  1347.         if (fio_flags == FIO_LATIN1 || fio_flags == FIO_UTF8)
  1348.         {
  1349.             p = ptr + size;
  1350.             if (fio_flags == FIO_UTF8)
  1351.             {
  1352.             /* Check for a trailing incomplete UTF-8 sequence */
  1353.             tail = ptr + size - 1;
  1354.             while (tail > ptr && (*tail & 0xc0) == 0x80)
  1355.                 --tail;
  1356.             if (tail + utf_byte2len(*tail) <= ptr + size)
  1357.                 tail = NULL;
  1358.             else
  1359.                 p = tail;
  1360.             }
  1361.         }
  1362.         else if (fio_flags & (FIO_UCS2 | FIO_UTF16))
  1363.         {
  1364.             /* Check for a trailing byte */
  1365.             p = ptr + (size & ~1);
  1366.             if (size & 1)
  1367.             tail = p;
  1368.             if ((fio_flags & FIO_UTF16) && p > ptr)
  1369.             {
  1370.             /* Check for a trailing leading word */
  1371.             if (fio_flags & FIO_ENDIAN_L)
  1372.             {
  1373.                 u8c = (*--p << 8);
  1374.                 u8c += *--p;
  1375.             }
  1376.             else
  1377.             {
  1378.                 u8c = *--p;
  1379.                 u8c += (*--p << 8);
  1380.             }
  1381.             if (u8c >= 0xd800 && u8c <= 0xdbff)
  1382.                 tail = p;
  1383.             else
  1384.                 p += 2;
  1385.             }
  1386.         }
  1387.         else /*  FIO_UCS4 */
  1388.         {
  1389.             /* Check for trailing 1, 2 or 3 bytes */
  1390.             p = ptr + (size & ~3);
  1391.             if (size & 3)
  1392.             tail = p;
  1393.         }
  1394.  
  1395.         /* If there is a trailing incomplete sequence move it to
  1396.          * conv_rest[]. */
  1397.         if (tail != NULL)
  1398.         {
  1399.             conv_restlen = (int)((ptr + size) - tail);
  1400.             mch_memmove(conv_rest, (char_u *)tail, conv_restlen);
  1401.             size -= conv_restlen;
  1402.         }
  1403.  
  1404.  
  1405.         while (p > ptr)
  1406.         {
  1407.             if (fio_flags & FIO_LATIN1)
  1408.             u8c = *--p;
  1409.             else if (fio_flags & (FIO_UCS2 | FIO_UTF16))
  1410.             {
  1411.             if (fio_flags & FIO_ENDIAN_L)
  1412.             {
  1413.                 u8c = (*--p << 8);
  1414.                 u8c += *--p;
  1415.             }
  1416.             else
  1417.             {
  1418.                 u8c = *--p;
  1419.                 u8c += (*--p << 8);
  1420.             }
  1421.             if ((fio_flags & FIO_UTF16)
  1422.                         && u8c >= 0xdc00 && u8c <= 0xdfff)
  1423.             {
  1424.                 int u16c;
  1425.  
  1426.                 if (p == ptr)
  1427.                 {
  1428.                 /* Missing leading word. */
  1429.                 if (can_retry)
  1430.                     goto rewind_retry;
  1431.                 conv_error = TRUE;
  1432.                 }
  1433.  
  1434.                 /* found second word of double-word, get the first
  1435.                  * word and compute the resulting character */
  1436.                 if (fio_flags & FIO_ENDIAN_L)
  1437.                 {
  1438.                 u16c = (*--p << 8);
  1439.                 u16c += *--p;
  1440.                 }
  1441.                 else
  1442.                 {
  1443.                 u16c = *--p;
  1444.                 u16c += (*--p << 8);
  1445.                 }
  1446.                 /* Check if the word is indeed a leading word. */
  1447.                 if (u16c < 0xd800 || u16c > 0xdbff)
  1448.                 {
  1449.                 if (can_retry)
  1450.                     goto rewind_retry;
  1451.                 conv_error = TRUE;
  1452.                 }
  1453.                 u8c = 0x10000 + ((u16c & 0x3ff) << 10)
  1454.                                   + (u8c & 0x3ff);
  1455.             }
  1456.             }
  1457.             else if (fio_flags & FIO_UCS4)
  1458.             {
  1459.             if (fio_flags & FIO_ENDIAN_L)
  1460.             {
  1461.                 u8c = (*--p << 24);
  1462.                 u8c += (*--p << 16);
  1463.                 u8c += (*--p << 8);
  1464.                 u8c += *--p;
  1465.             }
  1466.             else    /* big endian */
  1467.             {
  1468.                 u8c = *--p;
  1469.                 u8c += (*--p << 8);
  1470.                 u8c += (*--p << 16);
  1471.                 u8c += (*--p << 24);
  1472.             }
  1473.             }
  1474.             else    /* UTF-8 */
  1475.             {
  1476.             if (*--p < 0x80)
  1477.                 u8c = *p;
  1478.             else
  1479.             {
  1480.                 len = utf_head_off(ptr, p);
  1481.                 if (len == 0)
  1482.                 {
  1483.                 /* Not a valid UTF-8 character, retry with
  1484.                  * another fenc when possible, otherwise just
  1485.                  * report the error. */
  1486.                 if (can_retry)
  1487.                     goto rewind_retry;
  1488.                 conv_error = TRUE;
  1489.                 }
  1490.                 p -= len;
  1491.                 u8c = utf_ptr2char(p);
  1492.             }
  1493.             }
  1494.             if (enc_utf8)    /* produce UTF-8 */
  1495.             {
  1496.             dest -= utf_char2len(u8c);
  1497.             (void)utf_char2bytes(u8c, dest);
  1498.             }
  1499.             else        /* produce Latin1 */
  1500.             {
  1501.             --dest;
  1502.             if (u8c >= 0x100)
  1503.             {
  1504.                 /* character doesn't fit in latin1, retry with
  1505.                  * another fenc when possible, otherwise just
  1506.                  * report the error. */
  1507.                 if (can_retry)
  1508.                 goto rewind_retry;
  1509.                 *dest = 0xBF;
  1510.                 conv_error = TRUE;
  1511.             }
  1512.             else
  1513.                 *dest = u8c;
  1514.             }
  1515.         }
  1516.  
  1517.         /* move the linerest to before the converted characters */
  1518.         line_start = dest - linerest;
  1519.         mch_memmove(line_start, buffer, (size_t)linerest);
  1520.         size = (long)((ptr + real_size) - dest);
  1521.         ptr = dest;
  1522.         }
  1523.         else if (enc_utf8 && !conv_error && !curbuf->b_p_bin)
  1524.         {
  1525.         /* Reading UTF-8: Check if the bytes are valid UTF-8.
  1526.          * Need to start before "ptr" when part of the character was
  1527.          * read in the previous read() call. */
  1528.         for (p = ptr - utf_head_off(buffer, ptr); p < ptr + size; ++p)
  1529.         {
  1530.             if (*p >= 0x80)
  1531.             {
  1532.             len = utf_ptr2len_check(p);
  1533.             /* A length of 1 means it's an illegal byte.  Accept
  1534.              * an incomplete character at the end though, the next
  1535.              * read() will get the next bytes, we'll check it
  1536.              * then. */
  1537.             if (len == 1)
  1538.             {
  1539.                 p += utf_byte2len(*p) - 1;
  1540.                 break;
  1541.             }
  1542.             p += len - 1;
  1543.             }
  1544.         }
  1545.         if (p < ptr + size)
  1546.         {
  1547.             /* Detected a UTF-8 error. */
  1548.             if (can_retry)
  1549.             {
  1550. rewind_retry:
  1551.             /* Retry reading with another conversion. */
  1552. # if defined(FEAT_EVAL) && defined(USE_ICONV)
  1553.             if (*p_ccv != NUL && iconv_fd != (iconv_t)-1)
  1554.                 /* iconv() failed, try 'charconvert' */
  1555.                 did_iconv = TRUE;
  1556.             else
  1557. # endif
  1558.                 /* use next item from 'fileencodings' */
  1559.                 advance_fenc = TRUE;
  1560.             file_rewind = TRUE;
  1561.             goto retry;
  1562.             }
  1563.  
  1564.             /* There is no alternative fenc, just report the error. */
  1565. # ifdef USE_ICONV
  1566.             if (iconv_fd != (iconv_t)-1)
  1567.             conv_error = TRUE;
  1568.             else
  1569. # endif
  1570.             {
  1571.             char_u        *s;
  1572.  
  1573.             /* Estimate the line number. */
  1574.             illegal_byte = curbuf->b_ml.ml_line_count - linecnt + 1;
  1575.             for (s = ptr; s < p; ++s)
  1576.                 if (*s == '\n')
  1577.                 ++illegal_byte;
  1578.             }
  1579.         }
  1580.         }
  1581. #endif
  1582.  
  1583.         /* count the number of characters (after conversion!) */
  1584.         filesize += size;
  1585.  
  1586.         /*
  1587.          * when reading the first part of a file: guess EOL type
  1588.          */
  1589.         if (fileformat == EOL_UNKNOWN)
  1590.         {
  1591.         /* First try finding a NL, for Dos and Unix */
  1592.         if (try_dos || try_unix)
  1593.         {
  1594.             for (p = ptr; p < ptr + size; ++p)
  1595.             {
  1596.             if (*p == NL)
  1597.             {
  1598.                 if (!try_unix
  1599.                     || (try_dos && p > ptr && p[-1] == CR))
  1600.                 fileformat = EOL_DOS;
  1601.                 else
  1602.                 fileformat = EOL_UNIX;
  1603.                 break;
  1604.             }
  1605.             }
  1606.  
  1607.             /* Don't give in to EOL_UNIX if EOL_MAC is more likely */
  1608.             if (fileformat == EOL_UNIX && try_mac)
  1609.             {
  1610.             /* Need to reset the counters when retrying fenc. */
  1611.             try_mac = 1;
  1612.             try_unix = 1;
  1613.             for (; p >= ptr && *p != CR; p--)
  1614.                 ;
  1615.             if (p >= ptr)
  1616.             {
  1617.                 for (p = ptr; p < ptr + size; ++p)
  1618.                 {
  1619.                 if (*p == NL)
  1620.                     try_unix++;
  1621.                 else if (*p == CR)
  1622.                     try_mac++;
  1623.                 }
  1624.                 if (try_mac > try_unix)
  1625.                 fileformat = EOL_MAC;
  1626.             }
  1627.             }
  1628.         }
  1629.  
  1630.         /* No NL found: may use Mac format */
  1631.         if (fileformat == EOL_UNKNOWN && try_mac)
  1632.             fileformat = EOL_MAC;
  1633.  
  1634.         /* Still nothing found?  Use first format in 'ffs' */
  1635.         if (fileformat == EOL_UNKNOWN)
  1636.             fileformat = default_fileformat();
  1637.  
  1638.         /* if editing a new file: may set p_tx and p_ff */
  1639.         if (newfile)
  1640.             set_fileformat(fileformat, OPT_LOCAL);
  1641.         }
  1642.     }
  1643.  
  1644.     /*
  1645.      * This loop is executed once for every character read.
  1646.      * Keep it fast!
  1647.      */
  1648.     if (fileformat == EOL_MAC)
  1649.     {
  1650.         --ptr;
  1651.         while (++ptr, --size >= 0)
  1652.         {
  1653.         /* catch most common case first */
  1654.         if ((c = *ptr) != NUL && c != CR && c != NL)
  1655.             continue;
  1656.         if (c == NUL)
  1657.             *ptr = NL;    /* NULs are replaced by newlines! */
  1658.         else if (c == NL)
  1659.             *ptr = CR;    /* NLs are replaced by CRs! */
  1660.         else
  1661.         {
  1662.             if (skip_count == 0)
  1663.             {
  1664.             *ptr = NUL;        /* end of line */
  1665.             len = (colnr_T) (ptr - line_start + 1);
  1666.             if (ml_append(lnum, line_start, len, newfile) == FAIL)
  1667.             {
  1668.                 error = TRUE;
  1669.                 break;
  1670.             }
  1671.             ++lnum;
  1672.             if (--read_count == 0)
  1673.             {
  1674.                 error = TRUE;        /* break loop */
  1675.                 line_start = ptr;    /* nothing left to write */
  1676.                 break;
  1677.             }
  1678.             }
  1679.             else
  1680.             --skip_count;
  1681.             line_start = ptr + 1;
  1682.         }
  1683.         }
  1684.     }
  1685.     else
  1686.     {
  1687.         --ptr;
  1688.         while (++ptr, --size >= 0)
  1689.         {
  1690.         if ((c = *ptr) != NUL && c != NL)  /* catch most common case */
  1691.             continue;
  1692.         if (c == NUL)
  1693.             *ptr = NL;    /* NULs are replaced by newlines! */
  1694.         else
  1695.         {
  1696.             if (skip_count == 0)
  1697.             {
  1698.             *ptr = NUL;        /* end of line */
  1699.             len = (colnr_T)(ptr - line_start + 1);
  1700.             if (fileformat == EOL_DOS)
  1701.             {
  1702.                 if (ptr[-1] == CR)    /* remove CR */
  1703.                 {
  1704.                 ptr[-1] = NUL;
  1705.                 --len;
  1706.                 }
  1707.                 /*
  1708.                  * Reading in Dos format, but no CR-LF found!
  1709.                  * When 'fileformats' includes "unix", delete all
  1710.                  * the lines read so far and start all over again.
  1711.                  * Otherwise give an error message later.
  1712.                  */
  1713.                 else if (ff_error != EOL_DOS)
  1714.                 {
  1715.                 if (   try_unix
  1716.                     && !read_stdin
  1717.                     && (read_buffer
  1718.                     || lseek(fd, (off_t)0L, SEEK_SET) == 0))
  1719.                 {
  1720.                     fileformat = EOL_UNIX;
  1721.                     if (newfile)
  1722.                     set_fileformat(EOL_UNIX, OPT_LOCAL);
  1723.                     file_rewind = TRUE;
  1724.                     keep_fileformat = TRUE;
  1725.                     goto retry;
  1726.                 }
  1727.                 ff_error = EOL_DOS;
  1728.                 }
  1729.             }
  1730.             if (ml_append(lnum, line_start, len, newfile) == FAIL)
  1731.             {
  1732.                 error = TRUE;
  1733.                 break;
  1734.             }
  1735.             ++lnum;
  1736.             if (--read_count == 0)
  1737.             {
  1738.                 error = TRUE;        /* break loop */
  1739.                 line_start = ptr;    /* nothing left to write */
  1740.                 break;
  1741.             }
  1742.             }
  1743.             else
  1744.             --skip_count;
  1745.             line_start = ptr + 1;
  1746.         }
  1747.         }
  1748.     }
  1749.     linerest = (long)(ptr - line_start);
  1750.     ui_breakcheck();
  1751.     }
  1752.  
  1753. failed:
  1754.     /* not an error, max. number of lines reached */
  1755.     if (error && read_count == 0)
  1756.     error = FALSE;
  1757.  
  1758.     /*
  1759.      * If we get EOF in the middle of a line, note the fact and
  1760.      * complete the line ourselves.
  1761.      * In Dos format ignore a trailing CTRL-Z, unless 'binary' set.
  1762.      */
  1763.     if (!error
  1764.         && !got_int
  1765.         && linerest != 0
  1766.         && !(!curbuf->b_p_bin
  1767.         && fileformat == EOL_DOS
  1768.         && *line_start == Ctrl_Z
  1769.         && ptr == line_start + 1))
  1770.     {
  1771.     if (newfile)            /* remember for when writing */
  1772.         curbuf->b_p_eol = FALSE;
  1773.     *ptr = NUL;
  1774.     if (ml_append(lnum, line_start,
  1775.             (colnr_T)(ptr - line_start + 1), newfile) == FAIL)
  1776.         error = TRUE;
  1777.     else
  1778.         read_no_eol_lnum = ++lnum;
  1779.     }
  1780.  
  1781.     if (newfile)
  1782.     save_file_ff(curbuf);        /* remember the current file format */
  1783.  
  1784. #ifdef FEAT_CRYPT
  1785.     if (cryptkey != curbuf->b_p_key)
  1786.     vim_free(cryptkey);
  1787. #endif
  1788.  
  1789. #ifdef FEAT_MBYTE
  1790.     /* If editing a new file: set 'fenc' for the current buffer. */
  1791.     if (newfile)
  1792.     set_string_option_direct((char_u *)"fenc", -1, fenc,
  1793.                               OPT_FREE|OPT_LOCAL);
  1794.     if (fenc_alloced)
  1795.     vim_free(fenc);
  1796. # ifdef USE_ICONV
  1797.     if (iconv_fd != (iconv_t)-1)
  1798.     {
  1799.     iconv_close(iconv_fd);
  1800.     iconv_fd = (iconv_t)-1;
  1801.     }
  1802. # endif
  1803. #endif
  1804.  
  1805.     if (!read_buffer && !read_stdin)
  1806.     close(fd);                /* errors are ignored */
  1807.     vim_free(buffer);
  1808.  
  1809. #ifdef HAVE_DUP
  1810.     if (read_stdin)
  1811.     {
  1812.     /* Use stderr for stdin, makes shell commands work. */
  1813.     close(0);
  1814.     dup(2);
  1815.     }
  1816. #endif
  1817.  
  1818. #ifdef FEAT_MBYTE
  1819.     if (tmpname != NULL)
  1820.     {
  1821.     mch_remove(tmpname);        /* delete converted file */
  1822.     vim_free(tmpname);
  1823.     }
  1824. #endif
  1825.     --no_wait_return;            /* may wait for return now */
  1826.  
  1827.     /*
  1828.      * In recovery mode everything but autocommands is skipped.
  1829.      */
  1830.     if (!recoverymode)
  1831.     {
  1832.     /* need to delete the last line, which comes from the empty buffer */
  1833.     if (newfile && wasempty && !(curbuf->b_ml.ml_flags & ML_EMPTY))
  1834.     {
  1835. #ifdef FEAT_NETBEANS_INTG
  1836.         netbeansFireChanges = 0;
  1837. #endif
  1838.         ml_delete(curbuf->b_ml.ml_line_count, FALSE);
  1839. #ifdef FEAT_NETBEANS_INTG
  1840.         netbeansFireChanges = 1;
  1841. #endif
  1842.         --linecnt;
  1843.     }
  1844.     linecnt = curbuf->b_ml.ml_line_count - linecnt;
  1845.     if (filesize == 0)
  1846.         linecnt = 0;
  1847.     if (newfile || read_buffer)
  1848.         redraw_curbuf_later(NOT_VALID);
  1849.     else if (linecnt)        /* appended at least one line */
  1850.         appended_lines_mark(from, linecnt);
  1851.  
  1852. #ifdef FEAT_DIFF
  1853.     /* After reading the text into the buffer the diff info needs to be
  1854.      * updated. */
  1855.     if ((newfile || read_buffer))
  1856.         diff_invalidate();
  1857. #endif
  1858. #ifndef ALWAYS_USE_GUI
  1859.     /*
  1860.      * If we were reading from the same terminal as where messages go,
  1861.      * the screen will have been messed up.
  1862.      * Switch on raw mode now and clear the screen.
  1863.      */
  1864.     if (read_stdin)
  1865.     {
  1866.         settmode(TMODE_RAW);    /* set to raw mode */
  1867.         starttermcap();
  1868.         screenclear();
  1869.     }
  1870. #endif
  1871.  
  1872.     if (got_int)
  1873.     {
  1874.         if (!(flags & READ_DUMMY))
  1875.         {
  1876.         filemess(curbuf, sfname, (char_u *)_(e_interr), 0);
  1877.         if (newfile)
  1878.             curbuf->b_p_ro = TRUE;    /* must use "w!" now */
  1879.         }
  1880.         msg_scroll = msg_save;
  1881. #ifdef FEAT_VIMINFO
  1882.         check_marks_read();
  1883. #endif
  1884.         return OK;        /* an interrupt isn't really an error */
  1885.     }
  1886.  
  1887.     if (!filtering && !(flags & READ_DUMMY))
  1888.     {
  1889.         msg_add_fname(curbuf, sfname);   /* fname in IObuff with quotes */
  1890.         c = FALSE;
  1891.  
  1892. #ifdef UNIX
  1893. # ifdef S_ISFIFO
  1894.         if (S_ISFIFO(perm))                /* fifo or socket */
  1895.         {
  1896.         STRCAT(IObuff, _("[fifo/socket]"));
  1897.         c = TRUE;
  1898.         }
  1899. # else
  1900. #  ifdef S_IFIFO
  1901.         if ((perm & S_IFMT) == S_IFIFO)        /* fifo */
  1902.         {
  1903.         STRCAT(IObuff, _("[fifo]"));
  1904.         c = TRUE;
  1905.         }
  1906. #  endif
  1907. #  ifdef S_IFSOCK
  1908.         if ((perm & S_IFMT) == S_IFSOCK)        /* or socket */
  1909.         {
  1910.         STRCAT(IObuff, _("[socket]"));
  1911.         c = TRUE;
  1912.         }
  1913. #  endif
  1914. # endif
  1915. #endif
  1916.         if (curbuf->b_p_ro)
  1917.         {
  1918.         STRCAT(IObuff, shortmess(SHM_RO) ? _("[RO]") : _("[readonly]"));
  1919.         c = TRUE;
  1920.         }
  1921.         if (read_no_eol_lnum)
  1922.         {
  1923.         msg_add_eol();
  1924.         c = TRUE;
  1925.         }
  1926.         if (ff_error == EOL_DOS)
  1927.         {
  1928.         STRCAT(IObuff, _("[CR missing]"));
  1929.         c = TRUE;
  1930.         }
  1931.         if (ff_error == EOL_MAC)
  1932.         {
  1933.         STRCAT(IObuff, _("[NL found]"));
  1934.         c = TRUE;
  1935.         }
  1936.         if (split)
  1937.         {
  1938.         STRCAT(IObuff, _("[long lines split]"));
  1939.         c = TRUE;
  1940.         }
  1941. #ifdef FEAT_MBYTE
  1942.         if (notconverted)
  1943.         {
  1944.         STRCAT(IObuff, _("[NOT converted]"));
  1945.         c = TRUE;
  1946.         }
  1947.         else if (converted)
  1948.         {
  1949.         STRCAT(IObuff, _("[converted]"));
  1950.         c = TRUE;
  1951.         }
  1952. #endif
  1953. #ifdef FEAT_CRYPT
  1954.         if (cryptkey != NULL)
  1955.         {
  1956.         STRCAT(IObuff, _("[crypted]"));
  1957.         c = TRUE;
  1958.         }
  1959. #endif
  1960. #ifdef FEAT_MBYTE
  1961.         if (conv_error)
  1962.         {
  1963.         STRCAT(IObuff, _("[CONVERSION ERROR]"));
  1964.         c = TRUE;
  1965.         }
  1966.         else if (illegal_byte > 0)
  1967.         {
  1968.         sprintf((char *)IObuff + STRLEN(IObuff),
  1969.              _("[ILLEGAL BYTE in line %ld]"), (long)illegal_byte);
  1970.         c = TRUE;
  1971.         }
  1972.         else
  1973. #endif
  1974.         if (error)
  1975.         {
  1976.         STRCAT(IObuff, _("[READ ERRORS]"));
  1977.         c = TRUE;
  1978.         }
  1979.         if (msg_add_fileformat(fileformat))
  1980.         c = TRUE;
  1981. #ifdef FEAT_CRYPT
  1982.         if (cryptkey != NULL)
  1983.         msg_add_lines(c, (long)linecnt, filesize - CRYPT_MAGIC_LEN);
  1984.         else
  1985. #endif
  1986.         msg_add_lines(c, (long)linecnt, filesize);
  1987.  
  1988.         vim_free(keep_msg);
  1989.         keep_msg = NULL;
  1990.         msg_scrolled_ign = TRUE;
  1991. #ifdef ALWAYS_USE_GUI
  1992.         /* Don't show the message when reading stdin, it would end up in a
  1993.          * message box (which might be shown when exiting!) */
  1994.         if (read_stdin || read_buffer)
  1995.         p = msg_may_trunc(FALSE, IObuff);
  1996.         else
  1997. #endif
  1998.         p = msg_trunc_attr(IObuff, FALSE, 0);
  1999.         if (read_stdin || read_buffer || restart_edit != 0
  2000.             || (msg_scrolled && !need_wait_return))
  2001.         {
  2002.         /* Need to repeat the message after redrawing when:
  2003.          * - When reading from stdin (the screen will be cleared next).
  2004.          * - When restart_edit is set (otherwise there will be a delay
  2005.          *   before redrawing).
  2006.          * - When the screen was scrolled but there is no wait-return
  2007.          *   prompt. */
  2008.         set_keep_msg(p);
  2009.         keep_msg_attr = 0;
  2010.         }
  2011.         msg_scrolled_ign = FALSE;
  2012.     }
  2013.  
  2014.     /* with errors writing the file requires ":w!" */
  2015.     if (newfile && (error
  2016. #ifdef FEAT_MBYTE
  2017.             || conv_error
  2018. #endif
  2019.             ))
  2020.         curbuf->b_p_ro = TRUE;
  2021.  
  2022.     u_clearline();        /* cannot use "U" command after adding lines */
  2023.  
  2024.     /*
  2025.      * In Ex mode: cursor at last new line.
  2026.      * Otherwise: cursor at first new line.
  2027.      */
  2028.     if (exmode_active)
  2029.         curwin->w_cursor.lnum = from + linecnt;
  2030.     else
  2031.         curwin->w_cursor.lnum = from + 1;
  2032.     check_cursor_lnum();
  2033.     beginline(BL_WHITE | BL_FIX);        /* on first non-blank */
  2034.  
  2035.     /*
  2036.      * Set '[ and '] marks to the newly read lines.
  2037.      */
  2038.     curbuf->b_op_start.lnum = from + 1;
  2039.     curbuf->b_op_start.col = 0;
  2040.     curbuf->b_op_end.lnum = from + linecnt;
  2041.     curbuf->b_op_end.col = 0;
  2042.     }
  2043.     msg_scroll = msg_save;
  2044.  
  2045. #ifdef FEAT_VIMINFO
  2046.     /*
  2047.      * Get the marks before executing autocommands, so they can be used there.
  2048.      */
  2049.     check_marks_read();
  2050. #endif
  2051.  
  2052. #ifdef FEAT_AUTOCMD
  2053.     /*
  2054.      * Trick: We remember if the last line of the read didn't have
  2055.      * an eol for when writing it again.  This is required for
  2056.      * ":autocmd FileReadPost *.gz set bin|'[,']!gunzip" to work.
  2057.      */
  2058.     write_no_eol_lnum = read_no_eol_lnum;
  2059.  
  2060.     if (!read_stdin && !read_buffer)
  2061.     {
  2062.     int m = msg_scroll;
  2063.     int n = msg_scrolled;
  2064.  
  2065.     /* Save the fileformat now, otherwise the buffer will be considered
  2066.      * modified if the format/encoding was automatically detected. */
  2067.     if (newfile)
  2068.         save_file_ff(curbuf);
  2069.  
  2070.     /*
  2071.      * The output from the autocommands should not overwrite anything and
  2072.      * should not be overwritten: Set msg_scroll, restore its value if no
  2073.      * output was done.
  2074.      */
  2075.     msg_scroll = TRUE;
  2076.     if (filtering)
  2077.         apply_autocmds_exarg(EVENT_FILTERREADPOST, NULL, sfname,
  2078.                               FALSE, curbuf, eap);
  2079.     else if (newfile)
  2080.         apply_autocmds_exarg(EVENT_BUFREADPOST, NULL, sfname,
  2081.                               FALSE, curbuf, eap);
  2082.     else
  2083.         apply_autocmds_exarg(EVENT_FILEREADPOST, sfname, sfname,
  2084.                                 FALSE, NULL, eap);
  2085.     if (msg_scrolled == n)
  2086.         msg_scroll = m;
  2087. #ifdef FEAT_EVAL
  2088.     if (aborting())        /* autocmds may abort script processing */
  2089.         return FAIL;
  2090. #endif
  2091.     }
  2092. #endif
  2093.  
  2094.     if (recoverymode && error)
  2095.     return FAIL;
  2096.     return OK;
  2097. }
  2098.  
  2099. /*
  2100.  * Fill "*eap" to force the 'fileencoding' and 'fileformat' to be equal to the
  2101.  * buffer "buf".  Used for calling readfile().
  2102.  * Returns OK or FAIL.
  2103.  */
  2104.     int
  2105. prep_exarg(eap, buf)
  2106.     exarg_T    *eap;
  2107.     buf_T    *buf;
  2108. {
  2109.     eap->cmd = alloc((unsigned)(STRLEN(buf->b_p_ff)
  2110. #ifdef FEAT_MBYTE
  2111.         + STRLEN(buf->b_p_fenc)
  2112. #endif
  2113.                          + 15));
  2114.     if (eap->cmd == NULL)
  2115.     return FAIL;
  2116.  
  2117. #ifdef FEAT_MBYTE
  2118.     sprintf((char *)eap->cmd, "e ++ff=%s ++enc=%s", buf->b_p_ff, buf->b_p_fenc);
  2119.     eap->force_enc = 14 + (int)STRLEN(buf->b_p_ff);
  2120. #else
  2121.     sprintf((char *)eap->cmd, "e ++ff=%s", buf->b_p_ff);
  2122. #endif
  2123.     eap->force_ff = 7;
  2124.     return OK;
  2125. }
  2126.  
  2127. #ifdef FEAT_MBYTE
  2128. /*
  2129.  * Find next fileencoding to use from 'fileencodings'.
  2130.  * "pp" points to fenc_next.  It's advanced to the next item.
  2131.  * When there are no more items, an empty string is returned and *pp is set to
  2132.  * NULL.
  2133.  * When *pp is not set to NULL, the result is in allocated memory.
  2134.  */
  2135.     static char_u *
  2136. next_fenc(pp)
  2137.     char_u    **pp;
  2138. {
  2139.     char_u    *p;
  2140.     char_u    *r;
  2141.  
  2142.     if (**pp == NUL)
  2143.     {
  2144.     *pp = NULL;
  2145.     return (char_u *)"";
  2146.     }
  2147.     p = vim_strchr(*pp, ',');
  2148.     if (p == NULL)
  2149.     {
  2150.     r = enc_canonize(*pp);
  2151.     *pp += STRLEN(*pp);
  2152.     }
  2153.     else
  2154.     {
  2155.     r = vim_strnsave(*pp, (int)(p - *pp));
  2156.     *pp = p + 1;
  2157.     if (r != NULL)
  2158.     {
  2159.         p = enc_canonize(r);
  2160.         vim_free(r);
  2161.         r = p;
  2162.     }
  2163.     }
  2164.     if (r == NULL)    /* out of memory */
  2165.     {
  2166.     r = (char_u *)"";
  2167.     *pp = NULL;
  2168.     }
  2169.     return r;
  2170. }
  2171.  
  2172. # ifdef FEAT_EVAL
  2173. /*
  2174.  * Convert a file with the 'charconvert' expression.
  2175.  * This closes the file which is to be read, converts it and opens the
  2176.  * resulting file for reading.
  2177.  * Returns name of the resulting converted file (the caller should delete it
  2178.  * after reading it).
  2179.  * Returns NULL if the conversion failed ("*fdp" is not set) .
  2180.  */
  2181.     static char_u *
  2182. readfile_charconvert(fname, fenc, fdp)
  2183.     char_u    *fname;        /* name of input file */
  2184.     char_u    *fenc;        /* converted from */
  2185.     int        *fdp;        /* in/out: file descriptor of file */
  2186. {
  2187.     char_u    *tmpname;
  2188.     char_u    *errmsg = NULL;
  2189.  
  2190.     tmpname = vim_tempname('r');
  2191.     if (tmpname == NULL)
  2192.     errmsg = (char_u *)_("Can't find temp file for conversion");
  2193.     else
  2194.     {
  2195.     close(*fdp);        /* close the input file, ignore errors */
  2196.     *fdp = -1;
  2197.     if (eval_charconvert(fenc, enc_utf8 ? (char_u *)"utf-8" : p_enc,
  2198.                               fname, tmpname) == FAIL)
  2199.         errmsg = (char_u *)_("Conversion with 'charconvert' failed");
  2200.     if (errmsg == NULL && (*fdp = mch_open((char *)tmpname,
  2201.                           O_RDONLY | O_EXTRA, 0)) < 0)
  2202.         errmsg = (char_u *)_("can't read output of 'charconvert'");
  2203.     }
  2204.  
  2205.     if (errmsg != NULL)
  2206.     {
  2207.     /* Don't use emsg(), it breaks mappings, the retry with
  2208.      * another type of conversion might still work. */
  2209.     MSG(errmsg);
  2210.     if (tmpname != NULL)
  2211.     {
  2212.         mch_remove(tmpname);    /* delete converted file */
  2213.         vim_free(tmpname);
  2214.         tmpname = NULL;
  2215.     }
  2216.     }
  2217.  
  2218.     /* If the input file is closed, open it (caller should check for error). */
  2219.     if (*fdp < 0)
  2220.     *fdp = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
  2221.  
  2222.     return tmpname;
  2223. }
  2224. # endif
  2225.  
  2226. #endif
  2227.  
  2228. #ifdef FEAT_VIMINFO
  2229.     static void
  2230. check_marks_read()
  2231. {
  2232.     if (!curbuf->b_marks_read && get_viminfo_parameter('\'') > 0)
  2233.     {
  2234.     read_viminfo(NULL, FALSE, TRUE, FALSE);
  2235.     curbuf->b_marks_read = TRUE;
  2236.     }
  2237. }
  2238. #endif
  2239.  
  2240. #ifdef FEAT_CRYPT
  2241. /*
  2242.  * Check for magic number used for encryption.
  2243.  * If found, the magic number is removed from ptr[*sizep] and *sizep and
  2244.  * *filesizep are updated.
  2245.  * Return the (new) encryption key, NULL for no encryption.
  2246.  */
  2247.     static char_u *
  2248. check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile)
  2249.     char_u    *cryptkey;    /* previous encryption key or NULL */
  2250.     char_u    *ptr;        /* pointer to read bytes */
  2251.     long    *sizep;        /* length of read bytes */
  2252.     long    *filesizep;    /* nr of bytes used from file */
  2253.     int        newfile;    /* editing a new buffer */
  2254. {
  2255.     if (*sizep >= CRYPT_MAGIC_LEN
  2256.         && STRNCMP(ptr, CRYPT_MAGIC, CRYPT_MAGIC_LEN) == 0)
  2257.     {
  2258.     if (cryptkey == NULL)
  2259.     {
  2260.         if (*curbuf->b_p_key)
  2261.         cryptkey = curbuf->b_p_key;
  2262.         else
  2263.         {
  2264.         /* When newfile is TRUE, store the typed key
  2265.          * in the 'key' option and don't free it. */
  2266.         cryptkey = get_crypt_key(newfile, FALSE);
  2267.         /* check if empty key entered */
  2268.         if (cryptkey != NULL && *cryptkey == NUL)
  2269.         {
  2270.             if (cryptkey != curbuf->b_p_key)
  2271.             vim_free(cryptkey);
  2272.             cryptkey = NULL;
  2273.         }
  2274.         }
  2275.     }
  2276.  
  2277.     if (cryptkey != NULL)
  2278.     {
  2279.         crypt_init_keys(cryptkey);
  2280.  
  2281.         /* Remove magic number from the text */
  2282.         *filesizep += CRYPT_MAGIC_LEN;
  2283.         *sizep -= CRYPT_MAGIC_LEN;
  2284.         mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN, (size_t)*sizep);
  2285.     }
  2286.     }
  2287.     /* When starting to edit a new file which does not have
  2288.      * encryption, clear the 'key' option, except when
  2289.      * starting up (called with -x argument) */
  2290.     else if (newfile && *curbuf->b_p_key && !starting)
  2291.     set_option_value((char_u *)"key", 0L, (char_u *)"", OPT_LOCAL);
  2292.  
  2293.     return cryptkey;
  2294. }
  2295. #endif
  2296.  
  2297. #ifdef UNIX
  2298.     static void
  2299. set_file_time(fname, atime, mtime)
  2300.     char_u  *fname;
  2301.     time_t  atime;        /* access time */
  2302.     time_t  mtime;        /* modification time */
  2303. {
  2304. # if defined(HAVE_UTIME) && defined(HAVE_UTIME_H)
  2305.     struct utimbuf  buf;
  2306.  
  2307.     buf.actime    = atime;
  2308.     buf.modtime    = mtime;
  2309.     (void)utime((char *)fname, &buf);
  2310. # else
  2311. #  if defined(HAVE_UTIMES)
  2312.     struct timeval  tvp[2];
  2313.  
  2314.     tvp[0].tv_sec   = atime;
  2315.     tvp[0].tv_usec  = 0;
  2316.     tvp[1].tv_sec   = mtime;
  2317.     tvp[1].tv_usec  = 0;
  2318. #   ifdef NeXT
  2319.     (void)utimes((char *)fname, tvp);
  2320. #   else
  2321.     (void)utimes((char *)fname, &tvp);
  2322. #   endif
  2323. #  endif
  2324. # endif
  2325. }
  2326. #endif /* UNIX */
  2327.  
  2328. /*
  2329.  * buf_write() - write to file 'fname' lines 'start' through 'end'
  2330.  *
  2331.  * We do our own buffering here because fwrite() is so slow.
  2332.  *
  2333.  * If forceit is true, we don't care for errors when attempting backups (jw).
  2334.  * In case of an error everything possible is done to restore the original file.
  2335.  * But when forceit is TRUE, we risk loosing it.
  2336.  * When reset_changed is TRUE and start == 1 and end ==
  2337.  * curbuf->b_ml.ml_line_count, reset curbuf->b_changed.
  2338.  *
  2339.  * This function must NOT use NameBuff (because it's called by autowrite()).
  2340.  *
  2341.  * return FAIL for failure, OK otherwise
  2342.  */
  2343.     int
  2344. buf_write(buf, fname, sfname, start, end, eap, append, forceit,
  2345.                               reset_changed, filtering)
  2346.     buf_T        *buf;
  2347.     char_u        *fname;
  2348.     char_u        *sfname;
  2349.     linenr_T        start, end;
  2350.     exarg_T        *eap;        /* for forced 'ff' and 'fenc', can be
  2351.                        NULL! */
  2352.     int            append;
  2353.     int            forceit;
  2354.     int            reset_changed;
  2355.     int            filtering;
  2356. {
  2357.     int            fd;
  2358.     char_u        *backup = NULL;
  2359.     int            backup_copy = FALSE; /* copy the original file? */
  2360.     int            dobackup;
  2361.     char_u        *ffname;
  2362.     char_u        *wfname = NULL;    /* name of file to write to */
  2363.     char_u        *s;
  2364.     char_u        *ptr;
  2365.     char_u        c;
  2366.     int            len;
  2367.     linenr_T        lnum;
  2368.     long        nchars;
  2369.     char_u        *errmsg = NULL;
  2370.     char_u        *errnum = NULL;
  2371.     char_u        *buffer;
  2372.     char_u        smallbuf[SMBUFSIZE];
  2373.     char_u        *backup_ext;
  2374.     int            bufsize;
  2375.     long        perm;            /* file permissions */
  2376.     int            retval = OK;
  2377.     int            newfile = FALSE;        /* TRUE if file doesn't exist yet */
  2378.     int            msg_save = msg_scroll;
  2379.     int            overwriting;        /* TRUE if writing over original */
  2380.     int            no_eol = FALSE;        /* no end-of-line written */
  2381.     int            device = FALSE;        /* writing to a device */
  2382.     struct stat        st_old;
  2383.     int            prev_got_int = got_int;
  2384.     int            file_readonly = FALSE;  /* overwritten file is read-only */
  2385.     static char        *err_readonly = "is read-only (cannot override: \"W\" in 'cpoptions')";
  2386. #if defined(UNIX) || defined(__EMX__XX)        /*XXX fix me sometime? */
  2387.     int            made_writable = FALSE;  /* 'w' bit has been set */
  2388. #endif
  2389.                     /* writing everything */
  2390.     int            whole = (start == 1 && end == buf->b_ml.ml_line_count);
  2391. #ifdef FEAT_AUTOCMD
  2392.     linenr_T        old_line_count = buf->b_ml.ml_line_count;
  2393. #endif
  2394.     int            attr;
  2395.     int            fileformat;
  2396.     struct bw_info  write_info;        /* info for buf_write_bytes() */
  2397. #ifdef FEAT_MBYTE
  2398.     int            converted = FALSE;
  2399.     int            notconverted = FALSE;
  2400.     char_u        *fenc;        /* effective 'fileencoding' */
  2401.     char_u        *fenc_tofree = NULL; /* allocated "fenc" */
  2402. #endif
  2403. #ifdef HAS_BW_FLAGS
  2404.     int            wb_flags = 0;
  2405. #endif
  2406. #ifdef HAVE_ACL
  2407.     vim_acl_T        acl = NULL;        /* ACL copied from original file to
  2408.                        backup or new file */
  2409. #endif
  2410.  
  2411.     if (fname == NULL || *fname == NUL)    /* safety check */
  2412.     return FAIL;
  2413.  
  2414.     /*
  2415.      * Disallow writing from .exrc and .vimrc in current directory for
  2416.      * security reasons.
  2417.      */
  2418.     if (check_secure())
  2419.     return FAIL;
  2420.  
  2421.     /* Avoid a crash for a long name. */
  2422.     if (STRLEN(fname) >= MAXPATHL)
  2423.     {
  2424.     EMSG(_(e_longname));
  2425.     return FAIL;
  2426.     }
  2427.  
  2428. #ifdef FEAT_MBYTE
  2429.     /* must init bw_conv_buf and bw_iconv_fd before jumping to "fail" */
  2430.     write_info.bw_conv_buf = NULL;
  2431.     write_info.bw_conv_error = FALSE;
  2432.     write_info.bw_restlen = 0;
  2433. # ifdef USE_ICONV
  2434.     write_info.bw_iconv_fd = (iconv_t)-1;
  2435. # endif
  2436. #endif
  2437.  
  2438.     /*
  2439.      * If there is no file name yet, use the one for the written file.
  2440.      * BF_NOTEDITED is set to reflect this (in case the write fails).
  2441.      * Don't do this when the write is for a filter command.
  2442.      * Only do this when 'cpoptions' contains the 'f' flag.
  2443.      */
  2444.     if (reset_changed
  2445.         && whole
  2446.         && buf == curbuf
  2447.         && curbuf->b_ffname == NULL
  2448.         && !filtering
  2449.         && vim_strchr(p_cpo, CPO_FNAMEW) != NULL)
  2450.     {
  2451. #ifdef FEAT_AUTOCMD
  2452.     /* It's like the unnamed buffer is deleted.... */
  2453.     if (curbuf->b_p_bl)
  2454.         apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf);
  2455.     apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf);
  2456. #ifdef FEAT_EVAL
  2457.     if (aborting())        /* autocmds may abort script processing */
  2458.         return FAIL;
  2459. #endif
  2460. #endif
  2461.     if (setfname(fname, sfname, FALSE) == OK)
  2462.         curbuf->b_flags |= BF_NOTEDITED;
  2463. #ifdef FEAT_AUTOCMD
  2464.     /* ....and a new named one is created */
  2465.     apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, curbuf);
  2466.     if (curbuf->b_p_bl)
  2467.         apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, curbuf);
  2468. #endif
  2469.     }
  2470.  
  2471.     if (sfname == NULL)
  2472.     sfname = fname;
  2473.     /*
  2474.      * For Unix: Use the short file name whenever possible.
  2475.      * Avoids problems with networks and when directory names are changed.
  2476.      * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to
  2477.      * another directory, which we don't detect
  2478.      */
  2479.     ffname = fname;                /* remember full fname */
  2480. #ifdef UNIX
  2481.     fname = sfname;
  2482. #endif
  2483.  
  2484.     /* make sure we have a valid backup extension to use */
  2485.     if (*p_bex == NUL)
  2486. #ifdef RISCOS
  2487.     backup_ext = (char_u *)"/bak";
  2488. #else
  2489.     backup_ext = (char_u *)".bak";
  2490. #endif
  2491.     else
  2492.     backup_ext = p_bex;
  2493.  
  2494.     if (buf->b_ffname != NULL && fnamecmp(ffname, buf->b_ffname) == 0)
  2495.     overwriting = TRUE;
  2496.     else
  2497.     overwriting = FALSE;
  2498.  
  2499.     if (exiting)
  2500.     settmode(TMODE_COOK);        /* when exiting allow typahead now */
  2501.  
  2502.     ++no_wait_return;            /* don't wait for return yet */
  2503.  
  2504.     /*
  2505.      * Set '[ and '] marks to the lines to be written.
  2506.      */
  2507.     buf->b_op_start.lnum = start;
  2508.     buf->b_op_start.col = 0;
  2509.     buf->b_op_end.lnum = end;
  2510.     buf->b_op_end.col = 0;
  2511.  
  2512. #ifdef FEAT_AUTOCMD
  2513.     {
  2514.     aco_save_T    aco;
  2515.     int        buf_ffname = FALSE;
  2516.     int        buf_sfname = FALSE;
  2517.     int        buf_fname_f = FALSE;
  2518.     int        buf_fname_s = FALSE;
  2519.     int        did_cmd = FALSE;
  2520.  
  2521.     /*
  2522.      * Apply PRE aucocommands.
  2523.      * Set curbuf to the buffer to be written.
  2524.      * Careful: The autocommands may call buf_write() recursively!
  2525.      */
  2526.     if (ffname == buf->b_ffname)
  2527.         buf_ffname = TRUE;
  2528.     if (sfname == buf->b_sfname)
  2529.         buf_sfname = TRUE;
  2530.     if (fname == buf->b_ffname)
  2531.         buf_fname_f = TRUE;
  2532.     if (fname == buf->b_sfname)
  2533.         buf_fname_s = TRUE;
  2534.  
  2535.     /* set curwin/curbuf to buf and save a few things */
  2536.     aucmd_prepbuf(&aco, buf);
  2537.  
  2538.     if (append)
  2539.     {
  2540.         if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEAPPENDCMD,
  2541.                      sfname, sfname, FALSE, curbuf, eap)))
  2542.         apply_autocmds_exarg(EVENT_FILEAPPENDPRE,
  2543.                       sfname, sfname, FALSE, curbuf, eap);
  2544.     }
  2545.     else if (filtering)
  2546.     {
  2547.         apply_autocmds_exarg(EVENT_FILTERWRITEPRE,
  2548.                         NULL, sfname, FALSE, curbuf, eap);
  2549.     }
  2550.     else if (reset_changed && whole)
  2551.     {
  2552.         if (!(did_cmd = apply_autocmds_exarg(EVENT_BUFWRITECMD,
  2553.                      sfname, sfname, FALSE, curbuf, eap)))
  2554.         apply_autocmds_exarg(EVENT_BUFWRITEPRE,
  2555.                       sfname, sfname, FALSE, curbuf, eap);
  2556.     }
  2557.     else
  2558.     {
  2559.         if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEWRITECMD,
  2560.                      sfname, sfname, FALSE, curbuf, eap)))
  2561.         apply_autocmds_exarg(EVENT_FILEWRITEPRE,
  2562.                       sfname, sfname, FALSE, curbuf, eap);
  2563.     }
  2564.  
  2565.     /* restore curwin/curbuf and a few other things */
  2566.     aucmd_restbuf(&aco);
  2567.  
  2568.     /*
  2569.      * In three situations we return here and don't write the file:
  2570.      * 1. the autocommands deleted or unloaded the buffer.
  2571.      * 2. The autocommands abort script processing.
  2572.      * 3. If one of the "Cmd" autocommands was executed.
  2573.      */
  2574.     if (!buf_valid(buf))
  2575.         buf = NULL;
  2576.     if (buf == NULL || buf->b_ml.ml_mfp == NULL || did_cmd || aborting())
  2577.     {
  2578.         --no_wait_return;
  2579.         msg_scroll = msg_save;
  2580.         if (aborting())
  2581.         /* An aborting error, interrupt or exception in the
  2582.          * autocommands. */
  2583.         return FAIL;
  2584.         if (did_cmd)
  2585.         {
  2586.         if (buf == NULL)
  2587.             /* The buffer was deleted.  We assume it was written
  2588.              * (can't retry anyway). */
  2589.             return OK;
  2590.         if (overwriting)
  2591.         {
  2592.             /* Assume the buffer was written, update the timestamp. */
  2593.             ml_timestamp(buf);
  2594.             buf->b_flags &= ~BF_WRITE_MASK;
  2595.         }
  2596.         if (reset_changed && buf->b_changed)
  2597.             /* Buffer still changed, the autocommands didn't work
  2598.              * properly. */
  2599.             return FAIL;
  2600.         return OK;
  2601.         }
  2602. #ifdef FEAT_EVAL
  2603.         if (!aborting())
  2604. #endif
  2605.         EMSG(_("E203: Autocommands deleted or unloaded buffer to be written"));
  2606.         return FAIL;
  2607.     }
  2608.  
  2609.     /*
  2610.      * The autocommands may have changed the number of lines in the file.
  2611.      * When writing the whole file, adjust the end.
  2612.      * When writing part of the file, assume that the autocommands only
  2613.      * changed the number of lines that are to be written (tricky!).
  2614.      */
  2615.     if (buf->b_ml.ml_line_count != old_line_count)
  2616.     {
  2617.         if (whole)                        /* write all */
  2618.         end = buf->b_ml.ml_line_count;
  2619.         else if (buf->b_ml.ml_line_count > old_line_count)    /* more lines */
  2620.         end += buf->b_ml.ml_line_count - old_line_count;
  2621.         else                        /* less lines */
  2622.         {
  2623.         end -= old_line_count - buf->b_ml.ml_line_count;
  2624.         if (end < start)
  2625.         {
  2626.             --no_wait_return;
  2627.             msg_scroll = msg_save;
  2628.             EMSG(_("E204: Autocommand changed number of lines in unexpected way"));
  2629.             return FAIL;
  2630.         }
  2631.         }
  2632.     }
  2633.  
  2634.     /*
  2635.      * The autocommands may have changed the name of the buffer, which may
  2636.      * be kept in fname, ffname and sfname.
  2637.      */
  2638.     if (buf_ffname)
  2639.         ffname = buf->b_ffname;
  2640.     if (buf_sfname)
  2641.         sfname = buf->b_sfname;
  2642.     if (buf_fname_f)
  2643.         fname = buf->b_ffname;
  2644.     if (buf_fname_s)
  2645.         fname = buf->b_sfname;
  2646.     }
  2647. #endif
  2648.  
  2649.     if (shortmess(SHM_OVER) && !exiting)
  2650.     msg_scroll = FALSE;        /* overwrite previous file message */
  2651.     else
  2652.     msg_scroll = TRUE;        /* don't overwrite previous file message */
  2653.     if (!filtering)
  2654.     filemess(buf,
  2655. #ifndef UNIX
  2656.         sfname,
  2657. #else
  2658.         fname,
  2659. #endif
  2660.             (char_u *)"", 0);    /* show that we are busy */
  2661.     msg_scroll = FALSE;            /* always overwrite the file message now */
  2662.  
  2663.     buffer = alloc(BUFSIZE);
  2664.     if (buffer == NULL)            /* can't allocate big buffer, use small
  2665.                      * one (to be able to write when out of
  2666.                      * memory) */
  2667.     {
  2668.     buffer = smallbuf;
  2669.     bufsize = SMBUFSIZE;
  2670.     }
  2671.     else
  2672.     bufsize = BUFSIZE;
  2673.  
  2674.     /*
  2675.      * Get information about original file (if there is one).
  2676.      */
  2677. #if defined(UNIX) && !defined(ARCHIE)
  2678.     st_old.st_dev = st_old.st_ino = 0;
  2679.     perm = -1;
  2680.     if (mch_stat((char *)fname, &st_old) < 0)
  2681.     newfile = TRUE;
  2682.     else
  2683.     {
  2684.     perm = st_old.st_mode;
  2685.     if (!S_ISREG(st_old.st_mode))        /* not a file */
  2686.     {
  2687.         if (S_ISDIR(st_old.st_mode))
  2688.         {
  2689.         errnum = (char_u *)"E502: ";
  2690.         errmsg = (char_u *)_("is a directory");
  2691.         goto fail;
  2692.         }
  2693.         if (mch_nodetype(fname) != NODE_WRITABLE)
  2694.         {
  2695.         errnum = (char_u *)"E503: ";
  2696.         errmsg = (char_u *)_("is not a file or writable device");
  2697.         goto fail;
  2698.         }
  2699.         /* It's a device of some kind (or a fifo) which we can write to
  2700.          * but for which we can't make a backup. */
  2701.         device = TRUE;
  2702.         newfile = TRUE;
  2703.         perm = -1;
  2704.     }
  2705.     }
  2706. #else /* !UNIX */
  2707.     /*
  2708.      * Check for a writable device name.
  2709.      */
  2710.     c = mch_nodetype(fname);
  2711.     if (c == NODE_OTHER)
  2712.     {
  2713.     errnum = (char_u *)"E503: ";
  2714.     errmsg = (char_u *)_("is not a file or writable device");
  2715.     goto fail;
  2716.     }
  2717.     if (c == NODE_WRITABLE)
  2718.     {
  2719.     device = TRUE;
  2720.     newfile = TRUE;
  2721.     perm = -1;
  2722.     }
  2723.     else
  2724.     {
  2725.     perm = mch_getperm(fname);
  2726.     if (perm < 0)
  2727.         newfile = TRUE;
  2728.     else if (mch_isdir(fname))
  2729.     {
  2730.         errnum = (char_u *)"E502: ";
  2731.         errmsg = (char_u *)_("is a directory");
  2732.         goto fail;
  2733.     }
  2734.     if (overwriting)
  2735.         (void)mch_stat((char *)fname, &st_old);
  2736.     }
  2737. #endif /* !UNIX */
  2738.  
  2739.     if (!device && !newfile)
  2740.     {
  2741.     /*
  2742.      * Check if the file is really writable (when renaming the file to
  2743.      * make a backup we won't discover it later).
  2744.      */
  2745.     file_readonly = (
  2746. # ifdef USE_MCH_ACCESS
  2747. #  ifdef UNIX
  2748.             (perm & 0222) == 0 ||
  2749. #  endif
  2750.             mch_access((char *)fname, W_OK)
  2751. # else
  2752.             (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0
  2753.                            ? TRUE : (close(fd), FALSE)
  2754. # endif
  2755.             );
  2756.     if (!forceit && file_readonly)
  2757.     {
  2758.         if (vim_strchr(p_cpo, CPO_FWRITE) != NULL)
  2759.         {
  2760.         errnum = (char_u *)"E504: ";
  2761.         errmsg = (char_u *)_(err_readonly);
  2762.         }
  2763.         else
  2764.         {
  2765.         errnum = (char_u *)"E505: ";
  2766.         errmsg = (char_u *)_("is read-only (add ! to override)");
  2767.         }
  2768.         goto fail;
  2769.     }
  2770.  
  2771.     /*
  2772.      * Check if the timestamp hasn't changed since reading the file.
  2773.      */
  2774.     if (overwriting)
  2775.     {
  2776.         retval = check_mtime(buf, &st_old);
  2777.         if (retval == FAIL)
  2778.         goto fail;
  2779.     }
  2780.     }
  2781.  
  2782. #ifdef HAVE_ACL
  2783.     /*
  2784.      * For systems that support ACL: get the ACL from the original file.
  2785.      */
  2786.     if (!newfile)
  2787.     acl = mch_get_acl(fname);
  2788. #endif
  2789.  
  2790.     /*
  2791.      * If 'backupskip' is not empty, don't make a backup for some files.
  2792.      */
  2793.     dobackup = (p_wb || p_bk || *p_pm != NUL);
  2794. #ifdef FEAT_WILDIGN
  2795.     if (dobackup && *p_bsk != NUL && match_file_list(p_bsk, sfname, ffname))
  2796.     dobackup = FALSE;
  2797. #endif
  2798.  
  2799.     /*
  2800.      * Save the value of got_int and reset it.  We don't want a previous
  2801.      * interruption cancel writing, only hitting CTRL-C while writing should
  2802.      * abort it.
  2803.      */
  2804.     prev_got_int = got_int;
  2805.     got_int = FALSE;
  2806.  
  2807.     /* Mark the buffer as 'being saved' to prevent changed buffer warnings */
  2808.     buf->b_saving = TRUE;
  2809.  
  2810.     /*
  2811.      * If we are not appending or filtering, the file exists, and the
  2812.      * 'writebackup', 'backup' or 'patchmode' option is set, need a backup.
  2813.      * When 'patchmode' is set also make a backup when appending.
  2814.      *
  2815.      * Do not make any backup, if 'writebackup' and 'backup' are both switched
  2816.      * off.  This helps when editing large files on almost-full disks.
  2817.      */
  2818.     if (!(append && *p_pm == NUL) && !filtering && perm >= 0 && dobackup)
  2819.     {
  2820.     if (*p_bkc == 'y' || append)    /* "yes" */
  2821.         backup_copy = TRUE;
  2822. #if defined(UNIX) || defined(WIN32)
  2823.     else if (*p_bkc == 'a')        /* "auto" */
  2824.     {
  2825.         struct stat    st;
  2826.         int        i;
  2827.  
  2828. # ifdef UNIX
  2829.         /*
  2830.          * Don't rename the file when:
  2831.          * - it's a hard link
  2832.          * - it's a symbolic link
  2833.          * - we don't have write permission in the directory
  2834.          * - we can't set the owner/group of the new file
  2835.          */
  2836.         if (st_old.st_nlink > 1
  2837.             || mch_lstat((char *)fname, &st) < 0
  2838.             || st.st_dev != st_old.st_dev
  2839.             || st.st_ino != st_old.st_ino)
  2840.         backup_copy = TRUE;
  2841.         else
  2842. # endif
  2843.         {
  2844.         /*
  2845.          * Check if we can create a file and set the owner/group to
  2846.          * the ones from the original file.
  2847.          * First find a file name that doesn't exist yet (use some
  2848.          * arbitrary numbers).
  2849.          */
  2850.         STRCPY(IObuff, fname);
  2851.         for (i = 4913; ; i += 123)
  2852.         {
  2853.             sprintf((char *)gettail(IObuff), "%d", i);
  2854.             if (mch_stat((char *)IObuff, &st) < 0)
  2855.             break;
  2856.         }
  2857.         fd = mch_open((char *)IObuff, O_CREAT|O_WRONLY|O_EXCL, perm);
  2858.         close(fd);
  2859.         if (fd < 0)    /* can't write in directory */
  2860.             backup_copy = TRUE;
  2861.         else
  2862.         {
  2863. # ifdef UNIX
  2864.             chown((char *)IObuff, st_old.st_uid, st_old.st_gid);
  2865.             (void)mch_setperm(IObuff, perm);
  2866.             if (mch_stat((char *)IObuff, &st) < 0
  2867.                 || st.st_uid != st_old.st_uid
  2868.                 || st.st_gid != st_old.st_gid
  2869.                 || st.st_mode != perm)
  2870.             backup_copy = TRUE;
  2871. # endif
  2872.             mch_remove(IObuff);
  2873.         }
  2874.         }
  2875.     }
  2876. #endif
  2877.  
  2878.     if (backup_copy
  2879.         && (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) >= 0)
  2880.     {
  2881.         int        bfd;
  2882.         char_u    *copybuf, *wp;
  2883.         int        some_error = FALSE;
  2884.         struct stat    st_new;
  2885.         char_u    *dirp;
  2886.         char_u    *rootname;
  2887. #ifndef SHORT_FNAME
  2888.         int        did_set_shortname;
  2889. #endif
  2890.  
  2891.         copybuf = alloc(BUFSIZE + 1);
  2892.         if (copybuf == NULL)
  2893.         {
  2894.         some_error = TRUE;        /* out of memory */
  2895.         goto nobackup;
  2896.         }
  2897.  
  2898.         /*
  2899.          * Try to make the backup in each directory in the 'bdir' option.
  2900.          *
  2901.          * Unix semantics has it, that we may have a writable file,
  2902.          * that cannot be recreated with a simple open(..., O_CREAT, ) e.g:
  2903.          *  - the directory is not writable,
  2904.          *  - the file may be a symbolic link,
  2905.          *  - the file may belong to another user/group, etc.
  2906.          *
  2907.          * For these reasons, the existing writable file must be truncated
  2908.          * and reused. Creation of a backup COPY will be attempted.
  2909.          */
  2910.         dirp = p_bdir;
  2911.         while (*dirp)
  2912.         {
  2913. #ifdef UNIX
  2914.         st_new.st_ino = 0;
  2915.         st_new.st_dev = 0;
  2916.         st_new.st_gid = 0;
  2917. #endif
  2918.  
  2919.         /*
  2920.          * Isolate one directory name, using an entry in 'bdir'.
  2921.          */
  2922.         (void)copy_option_part(&dirp, copybuf, BUFSIZE, ",");
  2923.         rootname = get_file_in_dir(fname, copybuf);
  2924.         if (rootname == NULL)
  2925.         {
  2926.             some_error = TRUE;        /* out of memory */
  2927.             goto nobackup;
  2928.         }
  2929.  
  2930. #ifndef SHORT_FNAME
  2931.         did_set_shortname = FALSE;
  2932. #endif
  2933.  
  2934.         /*
  2935.          * May try twice if 'shortname' not set.
  2936.          */
  2937.         for (;;)
  2938.         {
  2939.             /*
  2940.              * Make backup file name.
  2941.              */
  2942.             backup = buf_modname(
  2943. #ifdef SHORT_FNAME
  2944.                 TRUE,
  2945. #else
  2946.                 (buf->b_p_sn || buf->b_shortname),
  2947. #endif
  2948.                          rootname, backup_ext, FALSE);
  2949.             if (backup == NULL)
  2950.             {
  2951.             vim_free(rootname);
  2952.             some_error = TRUE;        /* out of memory */
  2953.             goto nobackup;
  2954.             }
  2955.  
  2956.             /*
  2957.              * Check if backup file already exists.
  2958.              */
  2959.             if (mch_stat((char *)backup, &st_new) >= 0)
  2960.             {
  2961. #ifdef UNIX
  2962.             /*
  2963.              * Check if backup file is same as original file.
  2964.              * May happen when modname() gave the same file back.
  2965.              * E.g. silly link, or file name-length reached.
  2966.              * If we don't check here, we either ruin the file
  2967.              * when copying or erase it after writing. jw.
  2968.              */
  2969.             if (st_new.st_dev == st_old.st_dev
  2970.                         && st_new.st_ino == st_old.st_ino)
  2971.             {
  2972.                 vim_free(backup);
  2973.                 backup = NULL;    /* no backup file to delete */
  2974. # ifndef SHORT_FNAME
  2975.                 /*
  2976.                  * may try again with 'shortname' set
  2977.                  */
  2978.                 if (!(buf->b_shortname || buf->b_p_sn))
  2979.                 {
  2980.                 buf->b_shortname = TRUE;
  2981.                 did_set_shortname = TRUE;
  2982.                 continue;
  2983.                 }
  2984.                 /* setting shortname didn't help */
  2985.                 if (did_set_shortname)
  2986.                 buf->b_shortname = FALSE;
  2987. # endif
  2988.                 break;
  2989.             }
  2990. #endif
  2991.  
  2992.             /*
  2993.              * If we are not going to keep the backup file, don't
  2994.              * delete an existing one, try to use another name.
  2995.              * Change one character, just before the extension.
  2996.              */
  2997.             if (!p_bk)
  2998.             {
  2999.                 wp = backup + STRLEN(backup) - 1
  3000.                              - STRLEN(backup_ext);
  3001.                 if (wp < backup)    /* empty file name ??? */
  3002.                 wp = backup;
  3003.                 *wp = 'z';
  3004.                 while (*wp > 'a'
  3005.                     && mch_stat((char *)backup, &st_new) >= 0)
  3006.                 --*wp;
  3007.                 /* They all exist??? Must be something wrong. */
  3008.                 if (*wp == 'a')
  3009.                 {
  3010.                 vim_free(backup);
  3011.                 backup = NULL;
  3012.                 }
  3013.             }
  3014.             }
  3015.             break;
  3016.         }
  3017.         vim_free(rootname);
  3018.  
  3019.         /*
  3020.          * Try to create the backup file
  3021.          */
  3022.         if (backup != NULL)
  3023.         {
  3024.             /* remove old backup, if present */
  3025.             mch_remove(backup);
  3026.             /* Open with O_EXCL to avoid the file being created while
  3027.              * we were sleeping (symlink hacker attack?) */
  3028.             bfd = mch_open((char *)backup,
  3029.                        O_WRONLY|O_CREAT|O_EXTRA|O_EXCL, 0666);
  3030.             if (bfd < 0)
  3031.             {
  3032.             vim_free(backup);
  3033.             backup = NULL;
  3034.             }
  3035.             else
  3036.             {
  3037.             /* set file protection same as original file, but
  3038.              * strip s-bit */
  3039.             (void)mch_setperm(backup, perm & 0777);
  3040.  
  3041. #ifdef UNIX
  3042.             /*
  3043.              * Try to set the group of the backup same as the
  3044.              * original file. If this fails, set the protection
  3045.              * bits for the group same as the protection bits for
  3046.              * others.
  3047.              */
  3048.             if (st_new.st_gid != st_old.st_gid &&
  3049. # ifdef HAVE_FCHOWN  /* sequent-ptx lacks fchown() */
  3050.                     fchown(bfd, (uid_t)-1, st_old.st_gid) != 0
  3051. # else
  3052.               chown((char *)backup, (uid_t)-1, st_old.st_gid) != 0
  3053. # endif
  3054.                         )
  3055.                 mch_setperm(backup,
  3056.                       (perm & 0707) | ((perm & 07) << 3));
  3057. #endif
  3058.  
  3059.             /*
  3060.              * copy the file.
  3061.              */
  3062.             write_info.bw_fd = bfd;
  3063.             write_info.bw_buf = copybuf;
  3064. #ifdef HAS_BW_FLAGS
  3065.             write_info.bw_flags = FIO_NOCONVERT;
  3066. #endif
  3067.             while ((write_info.bw_len = vim_read(fd, copybuf,
  3068.                                 BUFSIZE)) > 0)
  3069.             {
  3070.                 if (buf_write_bytes(&write_info) == FAIL)
  3071.                 {
  3072.                 errmsg = (char_u *)_("E506: Can't write to backup file (add ! to override)");
  3073.                 break;
  3074.                 }
  3075.                 ui_breakcheck();
  3076.                 if (got_int)
  3077.                 {
  3078.                 errmsg = (char_u *)_(e_interr);
  3079.                 break;
  3080.                 }
  3081.             }
  3082.  
  3083.             if (close(bfd) < 0 && errmsg == NULL)
  3084.                 errmsg = (char_u *)_("E507: Close error for backup file (add ! to override)");
  3085.             if (write_info.bw_len < 0)
  3086.                 errmsg = (char_u *)_("E508: Can't read file for backup (add ! to override)");
  3087. #ifdef UNIX
  3088.             set_file_time(backup, st_old.st_atime, st_old.st_mtime);
  3089. #endif
  3090. #ifdef HAVE_ACL
  3091.             mch_set_acl(backup, acl);
  3092. #endif
  3093.             break;
  3094.             }
  3095.         }
  3096.         }
  3097.     nobackup:
  3098.         close(fd);        /* ignore errors for closing read file */
  3099.         vim_free(copybuf);
  3100.  
  3101.         if (backup == NULL && errmsg == NULL)
  3102.         errmsg = (char_u *)_("E509: Cannot create backup file (add ! to override)");
  3103.         /* ignore errors when forceit is TRUE */
  3104.         if ((some_error || errmsg != NULL) && !forceit)
  3105.         {
  3106.         retval = FAIL;
  3107.         goto fail;
  3108.         }
  3109.         errmsg = NULL;
  3110.     }
  3111.     else
  3112.     {
  3113.         char_u    *dirp;
  3114.         char_u    *p;
  3115.         char_u    *rootname;
  3116.  
  3117.         /*
  3118.          * Make a backup by renaming the original file.
  3119.          */
  3120.         /*
  3121.          * If 'cpoptions' includes the "W" flag, we don't want to
  3122.          * overwrite a read-only file.  But rename may be possible
  3123.          * anyway, thus we need an extra check here.
  3124.          */
  3125.         if (file_readonly && vim_strchr(p_cpo, CPO_FWRITE) != NULL)
  3126.         {
  3127.         errnum = (char_u *)"E504: ";
  3128.         errmsg = (char_u *)_(err_readonly);
  3129.         goto fail;
  3130.         }
  3131.  
  3132.         /*
  3133.          *
  3134.          * Form the backup file name - change path/fo.o.h to
  3135.          * path/fo.o.h.bak Try all directories in 'backupdir', first one
  3136.          * that works is used.
  3137.          */
  3138.         dirp = p_bdir;
  3139.         while (*dirp)
  3140.         {
  3141.         /*
  3142.          * Isolate one directory name and make the backup file name.
  3143.          */
  3144.         (void)copy_option_part(&dirp, IObuff, IOSIZE, ",");
  3145.         rootname = get_file_in_dir(fname, IObuff);
  3146.         if (rootname == NULL)
  3147.             backup = NULL;
  3148.         else
  3149.         {
  3150.             backup = buf_modname(
  3151. #ifdef SHORT_FNAME
  3152.                 TRUE,
  3153. #else
  3154.                 (buf->b_p_sn || buf->b_shortname),
  3155. #endif
  3156.                          rootname, backup_ext, FALSE);
  3157.             vim_free(rootname);
  3158.         }
  3159.  
  3160.         if (backup != NULL)
  3161.         {
  3162.             /*
  3163.              * If we are not going to keep the backup file, don't
  3164.              * delete an existing one, try to use another name.
  3165.              * Change one character, just before the extension.
  3166.              */
  3167.             if (!p_bk && mch_getperm(backup) >= 0)
  3168.             {
  3169.             p = backup + STRLEN(backup) - 1 - STRLEN(backup_ext);
  3170.             if (p < backup)    /* empty file name ??? */
  3171.                 p = backup;
  3172.             *p = 'z';
  3173.             while (*p > 'a' && mch_getperm(backup) >= 0)
  3174.                 --*p;
  3175.             /* They all exist??? Must be something wrong! */
  3176.             if (*p == 'a')
  3177.             {
  3178.                 vim_free(backup);
  3179.                 backup = NULL;
  3180.             }
  3181.             }
  3182.         }
  3183.         if (backup != NULL)
  3184.         {
  3185.  
  3186.             /*
  3187.              * Delete any existing backup and move the current version to
  3188.              * the backup.    For safety, we don't remove the backup until
  3189.              * the write has finished successfully. And if the 'backup'
  3190.              * option is set, leave it around.
  3191.              */
  3192.             /*
  3193.              * If the renaming of the original file to the backup file
  3194.              * works, quit here.
  3195.              */
  3196.             if (vim_rename(fname, backup) == 0)
  3197.             break;
  3198.  
  3199.             vim_free(backup);   /* don't do the rename below */
  3200.             backup = NULL;
  3201.         }
  3202.         }
  3203.         if (backup == NULL && !forceit)
  3204.         {
  3205.         errmsg = (char_u *)_("E510: Can't make backup file (add ! to override)");
  3206.         goto fail;
  3207.         }
  3208.     }
  3209.     }
  3210.  
  3211. #if defined(UNIX) && !defined(ARCHIE)
  3212.     /* When using ":w!" and the file was read-only: make it writable */
  3213.     if (forceit && st_old.st_uid == getuid() && perm >= 0 && !(perm & 0200)
  3214.                      && vim_strchr(p_cpo, CPO_FWRITE) == NULL)
  3215.     {
  3216.     perm |= 0200;
  3217.     (void)mch_setperm(fname, perm);
  3218.     made_writable = TRUE;
  3219.     }
  3220. #endif
  3221.  
  3222.     /* When using ":w!" and writing to the current file, readonly makes no
  3223.      * sense, reset it */
  3224.     if (forceit && overwriting)
  3225.     {
  3226.     buf->b_p_ro = FALSE;
  3227. #ifdef FEAT_TITLE
  3228.     need_maketitle = TRUE;        /* set window title later */
  3229. #endif
  3230. #ifdef FEAT_WINDOWS
  3231.     status_redraw_all();        /* redraw status lines later */
  3232. #endif
  3233.     }
  3234.  
  3235.     if (end > buf->b_ml.ml_line_count)
  3236.     end = buf->b_ml.ml_line_count;
  3237.     if (buf->b_ml.ml_flags & ML_EMPTY)
  3238.     start = end + 1;
  3239.  
  3240.     /*
  3241.      * If the original file is being overwritten, there is a small chance that
  3242.      * we crash in the middle of writing. Therefore the file is preserved now.
  3243.      * This makes all block numbers positive so that recovery does not need
  3244.      * the original file.
  3245.      * Don't do this if there is a backup file and we are exiting.
  3246.      */
  3247.     if (reset_changed && !newfile && !otherfile(ffname)
  3248.                           && !(exiting && backup != NULL))
  3249.     {
  3250.     ml_preserve(buf, FALSE);
  3251.     if (got_int)
  3252.     {
  3253.         errmsg = (char_u *)_(e_interr);
  3254.         goto restore_backup;
  3255.     }
  3256.     }
  3257.  
  3258. #ifdef MACOS_CLASSIC /* TODO: Is it need for MACOS_X? (Dany) */
  3259.     /*
  3260.      * Before risking to lose the original file verify if there's
  3261.      * a resource fork to preserve, and if cannot be done warn
  3262.      * the users. This happens when overwriting without backups.
  3263.      */
  3264.     if (backup == NULL && overwriting && !append)
  3265.     if (mch_has_resource_fork(fname))
  3266.     {
  3267.         errmsg = (char_u *)_("E460: The resource fork would be lost (add ! to override)");
  3268.         goto restore_backup;
  3269.     }
  3270. #endif
  3271.  
  3272. #ifdef VMS
  3273.     vms_remove_version(fname); /* remove version */
  3274. #endif
  3275.     /* Default: write the the file directly.  May write to a temp file for
  3276.      * multi-byte conversion. */
  3277.     wfname = fname;
  3278.  
  3279. #ifdef FEAT_MBYTE
  3280.     /* Check for forced 'fileencoding' from "++opt=val" argument. */
  3281.     if (eap != NULL && eap->force_enc != 0)
  3282.     {
  3283.     fenc = eap->cmd + eap->force_enc;
  3284.     fenc = enc_canonize(fenc);
  3285.     fenc_tofree = fenc;
  3286.     }
  3287.     else
  3288.     fenc = buf->b_p_fenc;
  3289.  
  3290.     /*
  3291.      * The file needs to be converted when 'fileencoding' is set and
  3292.      * 'fileencoding' differs from 'encoding'.
  3293.      */
  3294.     converted = (*fenc != NUL && !same_encoding(p_enc, fenc));
  3295.  
  3296.     /*
  3297.      * Check if UTF-8 to UCS-2/4 or Latin1 conversion needs to be done.  Or
  3298.      * Latin1 to Unicode conversion.  This is handled in buf_write_bytes().
  3299.      * Prepare the flags for it and allocate bw_conv_buf when needed.
  3300.      */
  3301.     if (converted && (enc_utf8 || STRCMP(p_enc, "latin1") == 0))
  3302.     {
  3303.     wb_flags = get_fio_flags(fenc);
  3304.     if (wb_flags & (FIO_UCS2 | FIO_UCS4 | FIO_UTF16 | FIO_UTF8))
  3305.     {
  3306.         /* Need to allocate a buffer to translate into. */
  3307.         if (wb_flags & (FIO_UCS2 | FIO_UTF16 | FIO_UTF8))
  3308.         write_info.bw_conv_buflen = bufsize * 2;
  3309.         else /* FIO_UCS4 */
  3310.         write_info.bw_conv_buflen = bufsize * 4;
  3311.         write_info.bw_conv_buf
  3312.                = lalloc((long_u)write_info.bw_conv_buflen, TRUE);
  3313.         if (write_info.bw_conv_buf == NULL)
  3314.         end = 0;
  3315.     }
  3316.     }
  3317.  
  3318. # ifdef WIN3264
  3319.     if (converted && wb_flags == 0 && get_win_fio_flags(fenc))
  3320.     {
  3321.     wb_flags = get_win_fio_flags(fenc);
  3322.  
  3323.     /* Convert UTF-8 -> UCS-2 and UCS-2 -> DBCS.  Worst-case * 4: */
  3324.     write_info.bw_conv_buflen = bufsize * 4;
  3325.     write_info.bw_conv_buf
  3326.                 = lalloc((long_u)write_info.bw_conv_buflen, TRUE);
  3327.     if (write_info.bw_conv_buf == NULL)
  3328.         end = 0;
  3329.     }
  3330. # endif
  3331.  
  3332. # if defined(FEAT_EVAL) || defined(USE_ICONV)
  3333.     if (converted && wb_flags == 0)
  3334.     {
  3335. #  ifdef USE_ICONV
  3336.     /*
  3337.      * Use iconv() conversion when conversion is needed and it's not done
  3338.      * internally.
  3339.      */
  3340.     write_info.bw_iconv_fd = (iconv_t)my_iconv_open(fenc,
  3341.                     enc_utf8 ? (char_u *)"utf-8" : p_enc);
  3342.     if (write_info.bw_iconv_fd != (iconv_t)-1)
  3343.     {
  3344.         /* We're going to use iconv(), allocate a buffer to convert in. */
  3345.         write_info.bw_conv_buflen = bufsize * ICONV_MULT;
  3346.         write_info.bw_conv_buf
  3347.                = lalloc((long_u)write_info.bw_conv_buflen, TRUE);
  3348.         if (write_info.bw_conv_buf == NULL)
  3349.         end = 0;
  3350.         write_info.bw_first = TRUE;
  3351.     }
  3352. #   ifdef FEAT_EVAL
  3353.     else
  3354. #   endif
  3355. #  endif
  3356.  
  3357. #  ifdef FEAT_EVAL
  3358.         /*
  3359.          * When the file needs to be converted with 'charconvert' after
  3360.          * writing, write to a temp file instead and let the conversion
  3361.          * overwrite the original file.
  3362.          */
  3363.         if (*p_ccv != NUL)
  3364.         {
  3365.         wfname = vim_tempname('w');
  3366.         if (wfname == NULL)    /* Can't write without a tempfile! */
  3367.         {
  3368.             errmsg = (char_u *)_("E214: Can't find temp file for writing");
  3369.             goto restore_backup;
  3370.         }
  3371.         }
  3372. #  endif
  3373.     }
  3374. # endif
  3375.     if (converted && wb_flags == 0
  3376. #  ifdef USE_ICONV
  3377.         && write_info.bw_iconv_fd == (iconv_t)-1
  3378. #  endif
  3379. #  ifdef FEAT_EVAL
  3380.         && wfname == fname
  3381. #  endif
  3382.         )
  3383.     {
  3384.     if (!forceit)
  3385.     {
  3386.         errmsg = (char_u *)_("E213: Cannot convert (add ! to write without conversion)");
  3387.         goto restore_backup;
  3388.     }
  3389.     notconverted = TRUE;
  3390.     }
  3391. #endif
  3392.  
  3393.     /*
  3394.      * Open the file "wfname" for writing.
  3395.      * We may try to open the file twice: If we can't write to the
  3396.      * file and forceit is TRUE we delete the existing file and try to create
  3397.      * a new one. If this still fails we may have lost the original file!
  3398.      * (this may happen when the user reached his quotum for number of files).
  3399.      * Appending will fail if the file does not exist and forceit is FALSE.
  3400.      */
  3401.     while ((fd = mch_open((char *)wfname, O_WRONLY | O_EXTRA | (append
  3402.             ? (forceit ? (O_APPEND | O_CREAT) : O_APPEND)
  3403.             : (O_CREAT | O_TRUNC))
  3404.             , 0666)) < 0)
  3405.     {
  3406.     /*
  3407.      * A forced write will try to create a new file if the old one is
  3408.      * still readonly. This may also happen when the directory is
  3409.      * read-only. In that case the mch_remove() will fail.
  3410.      */
  3411.     if (errmsg == NULL)
  3412.     {
  3413. #ifdef UNIX
  3414.         struct stat    st;
  3415.  
  3416.         /* Don't delete the file when it's a hard or symbolic link. */
  3417.         if ((!newfile && st_old.st_nlink > 1)
  3418.             || (mch_lstat((char *)fname, &st) == 0
  3419.             && (st.st_dev != st_old.st_dev
  3420.                 || st.st_ino != st_old.st_ino)))
  3421.         errmsg = (char_u *)_("E166: Can't open linked file for writing");
  3422.         else
  3423. #endif
  3424.         {
  3425.         errmsg = (char_u *)_("E212: Can't open file for writing");
  3426.         if (forceit && vim_strchr(p_cpo, CPO_FWRITE) == NULL
  3427.                                  && perm >= 0)
  3428.         {
  3429. #ifdef UNIX
  3430.             /* we write to the file, thus it should be marked
  3431.                writable after all */
  3432.             if (!(perm & 0200))
  3433.             made_writable = TRUE;
  3434.             perm |= 0200;
  3435.             if (st_old.st_uid != getuid() || st_old.st_gid != getgid())
  3436.             perm &= 0777;
  3437. #endif
  3438.             if (!append)        /* don't remove when appending */
  3439.             mch_remove(wfname);
  3440.             continue;
  3441.         }
  3442.         }
  3443.     }
  3444.  
  3445. restore_backup:
  3446.     {
  3447.         struct stat st;
  3448.  
  3449.         /*
  3450.          * If we failed to open the file, we don't need a backup. Throw it
  3451.          * away.  If we moved or removed the original file try to put the
  3452.          * backup in its place.
  3453.          */
  3454.         if (backup != NULL && wfname == fname)
  3455.         {
  3456.         if (backup_copy)
  3457.         {
  3458.             /*
  3459.              * There is a small chance that we removed the original,
  3460.              * try to move the copy in its place.
  3461.              * This may not work if the vim_rename() fails.
  3462.              * In that case we leave the copy around.
  3463.              */
  3464.             /* If file does not exist, put the copy in its place */
  3465.             if (mch_stat((char *)fname, &st) < 0)
  3466.             vim_rename(backup, fname);
  3467.             /* if original file does exist throw away the copy */
  3468.             if (mch_stat((char *)fname, &st) >= 0)
  3469.             mch_remove(backup);
  3470.         }
  3471.         else
  3472.         {
  3473.             /* try to put the original file back */
  3474.             vim_rename(backup, fname);
  3475.         }
  3476.         }
  3477.  
  3478.         /* if original file no longer exists give an extra warning */
  3479.         if (!newfile && mch_stat((char *)fname, &st) < 0)
  3480.         end = 0;
  3481.     }
  3482.  
  3483. #ifdef FEAT_MBYTE
  3484.     if (wfname != fname)
  3485.         vim_free(wfname);
  3486. #endif
  3487.     goto fail;
  3488.     }
  3489.     errmsg = NULL;
  3490.  
  3491. #if defined(MACOS_CLASSIC) || defined(WIN3264)
  3492.     /* TODO: Is it need for MACOS_X? (Dany) */
  3493.     /*
  3494.      * On macintosh copy the original files attributes (i.e. the backup)
  3495.      * This is done in order to preserve the ressource fork and the
  3496.      * Finder attribute (label, comments, custom icons, file creatore)
  3497.      */
  3498.     if (backup != NULL && overwriting && !append)
  3499.     {
  3500.     if (backup_copy)
  3501.         (void)mch_copy_file_attribute(wfname, backup);
  3502.     else
  3503.         (void)mch_copy_file_attribute(backup, wfname);
  3504.     }
  3505.  
  3506.     if (!overwriting && !append)
  3507.     {
  3508.     if (buf->b_ffname != NULL)
  3509.         (void)mch_copy_file_attribute(buf->b_ffname, wfname);
  3510.     /* Should copy ressource fork */
  3511.     }
  3512. #endif
  3513.  
  3514.     write_info.bw_fd = fd;
  3515.  
  3516. #ifdef FEAT_CRYPT
  3517.     if (*buf->b_p_key && !filtering)
  3518.     {
  3519.     crypt_init_keys(buf->b_p_key);
  3520.     /* Write magic number, so that Vim knows that this file is encrypted
  3521.      * when reading it again.  This also undergoes utf-8 to ucs-2/4
  3522.      * conversion when needed. */
  3523.     write_info.bw_buf = (char_u *)CRYPT_MAGIC;
  3524.     write_info.bw_len = CRYPT_MAGIC_LEN;
  3525.     write_info.bw_flags = FIO_NOCONVERT;
  3526.     if (buf_write_bytes(&write_info) == FAIL)
  3527.         end = 0;
  3528.     wb_flags |= FIO_ENCRYPTED;
  3529.     }
  3530. #endif
  3531.  
  3532.     write_info.bw_buf = buffer;
  3533.     nchars = 0;
  3534.  
  3535. #ifdef FEAT_MBYTE
  3536.     /*
  3537.      * The BOM is written just after the encryption magic number.
  3538.      */
  3539.     if (buf->b_p_bomb && !buf->b_p_bin)
  3540.     {
  3541.     write_info.bw_len = make_bom(buffer, fenc);
  3542.     if (write_info.bw_len > 0)
  3543.     {
  3544.         /* don't convert, do encryption */
  3545.         write_info.bw_flags = FIO_NOCONVERT | wb_flags;
  3546.         if (buf_write_bytes(&write_info) == FAIL)
  3547.         end = 0;
  3548.         else
  3549.         nchars += write_info.bw_len;
  3550.     }
  3551.     }
  3552. #endif
  3553.  
  3554.     write_info.bw_len = bufsize;
  3555. #ifdef HAS_BW_FLAGS
  3556.     write_info.bw_flags = wb_flags;
  3557. #endif
  3558.     fileformat = get_fileformat_force(buf, eap);
  3559.     s = buffer;
  3560.     len = 0;
  3561.     for (lnum = start; lnum <= end; ++lnum)
  3562.     {
  3563.     /*
  3564.      * The next while loop is done once for each character written.
  3565.      * Keep it fast!
  3566.      */
  3567.     ptr = ml_get_buf(buf, lnum, FALSE) - 1;
  3568.     while ((c = *++ptr) != NUL)
  3569.     {
  3570.         if (c == NL)
  3571.         *s = NUL;        /* replace newlines with NULs */
  3572.         else if (c == CR && fileformat == EOL_MAC)
  3573.         *s = NL;        /* Mac: replace CRs with NLs */
  3574.         else
  3575.         *s = c;
  3576.         ++s;
  3577.         if (++len != bufsize)
  3578.         continue;
  3579.         if (buf_write_bytes(&write_info) == FAIL)
  3580.         {
  3581.         end = 0;        /* write error: break loop */
  3582.         break;
  3583.         }
  3584.         nchars += bufsize;
  3585.         s = buffer;
  3586.         len = 0;
  3587.     }
  3588.     /* write failed or last line has no EOL: stop here */
  3589.     if (end == 0
  3590.         || (lnum == end
  3591.             && buf->b_p_bin
  3592.             && (lnum == write_no_eol_lnum
  3593.             || (lnum == buf->b_ml.ml_line_count && !buf->b_p_eol))))
  3594.     {
  3595.         ++lnum;            /* written the line, count it */
  3596.         no_eol = TRUE;
  3597.         break;
  3598.     }
  3599.     if (fileformat == EOL_UNIX)
  3600.         *s++ = NL;
  3601.     else
  3602.     {
  3603.         *s++ = CR;            /* EOL_MAC or EOL_DOS: write CR */
  3604.         if (fileformat == EOL_DOS)    /* write CR-NL */
  3605.         {
  3606.         if (++len == bufsize)
  3607.         {
  3608.             if (buf_write_bytes(&write_info) == FAIL)
  3609.             {
  3610.             end = 0;    /* write error: break loop */
  3611.             break;
  3612.             }
  3613.             nchars += bufsize;
  3614.             s = buffer;
  3615.             len = 0;
  3616.         }
  3617.         *s++ = NL;
  3618.         }
  3619.     }
  3620.     if (++len == bufsize && end)
  3621.     {
  3622.         if (buf_write_bytes(&write_info) == FAIL)
  3623.         {
  3624.         end = 0;        /* write error: break loop */
  3625.         break;
  3626.         }
  3627.         nchars += bufsize;
  3628.         s = buffer;
  3629.         len = 0;
  3630.  
  3631.         ui_breakcheck();
  3632.         if (got_int)
  3633.         {
  3634.         end = 0;        /* Interrupted, break loop */
  3635.         break;
  3636.         }
  3637.     }
  3638. #ifdef VMS
  3639.     /*
  3640.      * On VMS there is a problem: newlines get added when writing blocks
  3641.      * at a time. Fix it by writing a line at a time.
  3642.      * This is much slower!
  3643.      * Explanation: Vim can not handle, so far, variable record format.
  3644.      * With $analize/rms filename you can get the rms file structure, and
  3645.      * if the Record format filed is variable, CR will be added after
  3646.      * every written buffer.  In other cases it works without this fix.
  3647.      * From other side read is about 5 times slower for "variable record
  3648.      * format" files.
  3649.      */
  3650.     if (buf->b_fab_rfm == FAB$C_VAR)
  3651.     {
  3652.         write_info.bw_len = len;
  3653.         if (buf_write_bytes(&write_info) == FAIL)
  3654.         {
  3655.         end = 0;        /* write error: break loop */
  3656.         break;
  3657.         }
  3658.         write_info.bw_len = bufsize;
  3659.         nchars += len;
  3660.         s = buffer;
  3661.         len = 0;
  3662.     }
  3663. #endif
  3664.     }
  3665.     if (len > 0 && end > 0)
  3666.     {
  3667.     write_info.bw_len = len;
  3668.     if (buf_write_bytes(&write_info) == FAIL)
  3669.         end = 0;            /* write error */
  3670.     nchars += len;
  3671.     }
  3672.  
  3673.     if (close(fd) != 0)
  3674.     {
  3675.     errmsg = (char_u *)_("E512: Close failed");
  3676.     end = 0;
  3677.     }
  3678.  
  3679. #ifdef UNIX
  3680.     if (made_writable)
  3681.     perm &= ~0200;        /* reset 'w' bit for security reasons */
  3682. #endif
  3683.     if (perm >= 0)        /* set perm. of new file same as old file */
  3684.     (void)mch_setperm(wfname, perm);
  3685. #ifdef RISCOS
  3686.     if (!append && !filtering)
  3687.     /* Set the filetype after writing the file. */
  3688.     mch_set_filetype(wfname, buf->b_p_oft);
  3689. #endif
  3690. #ifdef HAVE_ACL
  3691.     /* Probably need to set the ACL before changing the user (can't set the
  3692.      * ACL on a file the user doesn't own). */
  3693.     if (!backup_copy)
  3694.     mch_set_acl(wfname, acl);
  3695. #endif
  3696.  
  3697. #ifdef UNIX
  3698.     /* When creating a new file, set its owner/group to that of the original
  3699.      * file.  Get the new device and inode number. */
  3700.     if (backup != NULL && !backup_copy)
  3701.     {
  3702.     struct stat    st;
  3703.  
  3704.     /* don't change the owner when it's already OK, some systems remove
  3705.      * permission or ACL stuff */
  3706.     if (mch_stat((char *)wfname, &st) < 0
  3707.         || st.st_uid != st_old.st_uid
  3708.         || st.st_gid != st_old.st_gid)
  3709.     {
  3710.         chown((char *)wfname, st_old.st_uid, st_old.st_gid);
  3711.         if (perm >= 0)    /* set permission again, may have changed */
  3712.         (void)mch_setperm(wfname, perm);
  3713.     }
  3714.     buf_setino(buf);
  3715.     }
  3716. #endif
  3717.  
  3718.  
  3719. #if defined(FEAT_MBYTE) && defined(FEAT_EVAL)
  3720.     if (wfname != fname)
  3721.     {
  3722.     /*
  3723.      * The file was written to a temp file, now it needs to be converted
  3724.      * with 'charconvert' to (overwrite) the output file.
  3725.      */
  3726.     if (end != 0)
  3727.     {
  3728.         if (eval_charconvert(enc_utf8 ? (char_u *)"utf-8" : p_enc, fenc,
  3729.                                wfname, fname) == FAIL)
  3730.         {
  3731.         write_info.bw_conv_error = TRUE;
  3732.         end = 0;
  3733.         }
  3734.     }
  3735.     mch_remove(wfname);
  3736.     vim_free(wfname);
  3737.     }
  3738. #endif
  3739.  
  3740.     if (end == 0)
  3741.     {
  3742.     if (errmsg == NULL)
  3743.     {
  3744. #ifdef FEAT_MBYTE
  3745.         if (write_info.bw_conv_error)
  3746.         errmsg = (char_u *)_("E513: write error, conversion failed");
  3747.         else
  3748. #endif
  3749.         if (got_int)
  3750.             errmsg = (char_u *)_(e_interr);
  3751.         else
  3752.             errmsg = (char_u *)_("E514: write error (file system full?)");
  3753.     }
  3754.  
  3755.     /*
  3756.      * If we have a backup file, try to put it in place of the new file,
  3757.      * because the new file is probably corrupt.  This avoids loosing the
  3758.      * original file when trying to make a backup when writing the file a
  3759.      * second time.
  3760.      * When "backup_copy" is set we need to copy the backup over the new
  3761.      * file.  Otherwise rename the backup file.
  3762.      * If this is OK, don't give the extra warning message.
  3763.      */
  3764.     if (backup != NULL)
  3765.     {
  3766.         if (backup_copy)
  3767.         {
  3768.         /* This may take a while, if we were interrupted let the user
  3769.          * know we got the message. */
  3770.         if (got_int)
  3771.         {
  3772.             MSG(_(e_interr));
  3773.             out_flush();
  3774.         }
  3775.         if ((fd = mch_open((char *)backup, O_RDONLY | O_EXTRA, 0)) >= 0)
  3776.         {
  3777.             if ((write_info.bw_fd = mch_open((char *)fname,
  3778.               O_WRONLY | O_CREAT | O_TRUNC | O_EXTRA, 0666)) >= 0)
  3779.             {
  3780.             /* copy the file. */
  3781.             write_info.bw_buf = smallbuf;
  3782. #ifdef HAS_BW_FLAGS
  3783.             write_info.bw_flags = FIO_NOCONVERT;
  3784. #endif
  3785.             while ((write_info.bw_len = vim_read(fd, smallbuf,
  3786.                               SMBUFSIZE)) > 0)
  3787.                 if (buf_write_bytes(&write_info) == FAIL)
  3788.                 break;
  3789.  
  3790.             if (close(write_info.bw_fd) >= 0
  3791.                            && write_info.bw_len == 0)
  3792.                 end = 1;        /* success */
  3793.             }
  3794.             close(fd);    /* ignore errors for closing read file */
  3795.         }
  3796.         }
  3797.         else
  3798.         {
  3799.         if (vim_rename(backup, fname) == 0)
  3800.             end = 1;
  3801.         }
  3802.     }
  3803.     goto fail;
  3804.     }
  3805.  
  3806.     lnum -= start;        /* compute number of written lines */
  3807.     --no_wait_return;        /* may wait for return now */
  3808.  
  3809. #if !(defined(UNIX) || defined(VMS))
  3810.     fname = sfname;        /* use shortname now, for the messages */
  3811. #endif
  3812.     if (!filtering)
  3813.     {
  3814.     msg_add_fname(buf, fname);    /* put fname in IObuff with quotes */
  3815.     c = FALSE;
  3816. #ifdef FEAT_MBYTE
  3817.     if (write_info.bw_conv_error)
  3818.     {
  3819.         STRCAT(IObuff, _(" CONVERSION ERROR"));
  3820.         c = TRUE;
  3821.     }
  3822.     else if (notconverted)
  3823.     {
  3824.         STRCAT(IObuff, _("[NOT converted]"));
  3825.         c = TRUE;
  3826.     }
  3827.     else if (converted)
  3828.     {
  3829.         STRCAT(IObuff, _("[converted]"));
  3830.         c = TRUE;
  3831.     }
  3832. #endif
  3833.     if (device)
  3834.     {
  3835.         STRCAT(IObuff, _("[Device]"));
  3836.         c = TRUE;
  3837.     }
  3838.     else if (newfile)
  3839.     {
  3840.         STRCAT(IObuff, shortmess(SHM_NEW) ? _("[New]") : _("[New File]"));
  3841.         c = TRUE;
  3842.     }
  3843.     if (no_eol)
  3844.     {
  3845.         msg_add_eol();
  3846.         c = TRUE;
  3847.     }
  3848.     /* may add [unix/dos/mac] */
  3849.     if (msg_add_fileformat(fileformat))
  3850.         c = TRUE;
  3851. #ifdef FEAT_CRYPT
  3852.     if (wb_flags & FIO_ENCRYPTED)
  3853.     {
  3854.         STRCAT(IObuff, _("[crypted]"));
  3855.         c = TRUE;
  3856.     }
  3857. #endif
  3858.     msg_add_lines(c, (long)lnum, nchars);    /* add line/char count */
  3859.     if (!shortmess(SHM_WRITE))
  3860.     {
  3861.         if (append)
  3862.         STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [a]") : _(" appended"));
  3863.         else
  3864.         STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [w]") : _(" written"));
  3865.     }
  3866.  
  3867.     set_keep_msg(msg_trunc_attr(IObuff, FALSE, 0));
  3868.     keep_msg_attr = 0;
  3869.     }
  3870.  
  3871.     if (reset_changed && whole
  3872. #ifdef FEAT_MBYTE
  3873.         && !write_info.bw_conv_error
  3874. #endif
  3875.         )        /* when written everything correctly */
  3876.     {
  3877.     unchanged(buf, TRUE);
  3878.     u_unchanged(buf);
  3879. #ifdef FEAT_NETBEANS_INTG
  3880.     netbeans_saved(buf);
  3881. #endif
  3882.     }
  3883.  
  3884.     /*
  3885.      * If written to the current file, update the timestamp of the swap file
  3886.      * and reset the BF_WRITE_MASK flags. Also sets buf->b_mtime.
  3887.      */
  3888.     if (overwriting)
  3889.     {
  3890.     ml_timestamp(buf);
  3891.     buf->b_flags &= ~BF_WRITE_MASK;
  3892.     }
  3893.  
  3894.     /*
  3895.      * If we kept a backup until now, and we are in patch mode, then we make
  3896.      * the backup file our 'original' file.
  3897.      */
  3898.     if (*p_pm && dobackup)
  3899.     {
  3900.     char *org = (char *)buf_modname(
  3901. #ifdef SHORT_FNAME
  3902.                     TRUE,
  3903. #else
  3904.                     (buf->b_p_sn || buf->b_shortname),
  3905. #endif
  3906.                               fname, p_pm, FALSE);
  3907.  
  3908.     if (backup != NULL)
  3909.     {
  3910.         struct stat st;
  3911.  
  3912.         /*
  3913.          * If the original file does not exist yet
  3914.          * the current backup file becomes the original file
  3915.          */
  3916.         if (org == NULL)
  3917.         EMSG(_("E205: Patchmode: can't save original file"));
  3918.         else if (mch_stat(org, &st) < 0)
  3919.         {
  3920.         vim_rename(backup, (char_u *)org);
  3921.         vim_free(backup);        /* don't delete the file */
  3922.         backup = NULL;
  3923. #ifdef UNIX
  3924.         set_file_time((char_u *)org, st_old.st_atime, st_old.st_mtime);
  3925. #endif
  3926.         }
  3927.     }
  3928.     /*
  3929.      * If there is no backup file, remember that a (new) file was
  3930.      * created.
  3931.      */
  3932.     else
  3933.     {
  3934.         int empty_fd;
  3935.  
  3936.         if (org == NULL
  3937.             || (empty_fd = mch_open(org, O_CREAT | O_EXTRA | O_EXCL,
  3938.                                    0666)) < 0)
  3939.           EMSG(_("E206: patchmode: can't touch empty original file"));
  3940.         else
  3941.           close(empty_fd);
  3942.     }
  3943.     if (org != NULL)
  3944.     {
  3945.         mch_setperm((char_u *)org, mch_getperm(fname) & 0777);
  3946.         vim_free(org);
  3947.     }
  3948.     }
  3949.  
  3950.     /*
  3951.      * Remove the backup unless 'backup' option is set
  3952.      */
  3953.     if (!p_bk && backup != NULL && mch_remove(backup) != 0)
  3954.     EMSG(_("E207: Can't delete backup file"));
  3955.  
  3956. #ifdef FEAT_SUN_WORKSHOP
  3957.     if (usingSunWorkShop)
  3958.     workshop_file_saved((char *) ffname);
  3959. #endif
  3960.  
  3961.     goto nofail;
  3962.  
  3963.     /*
  3964.      * Finish up.  We get here either after failure or success.
  3965.      */
  3966. fail:
  3967.     --no_wait_return;        /* may wait for return now */
  3968. nofail:
  3969.  
  3970.     /* Done saving, we accept changed buffer warnings again */
  3971.     buf->b_saving = FALSE;
  3972.  
  3973.     vim_free(backup);
  3974.     if (buffer != smallbuf)
  3975.     vim_free(buffer);
  3976. #ifdef FEAT_MBYTE
  3977.     vim_free(fenc_tofree);
  3978.     vim_free(write_info.bw_conv_buf);
  3979. # ifdef USE_ICONV
  3980.     if (write_info.bw_iconv_fd != (iconv_t)-1)
  3981.     {
  3982.     iconv_close(write_info.bw_iconv_fd);
  3983.     write_info.bw_iconv_fd = (iconv_t)-1;
  3984.     }
  3985. # endif
  3986. #endif
  3987. #ifdef HAVE_ACL
  3988.     mch_free_acl(acl);
  3989. #endif
  3990.  
  3991.     if (errmsg != NULL)
  3992.     {
  3993.     int numlen = errnum != NULL ? STRLEN(errnum) : 0;
  3994.  
  3995.     attr = hl_attr(HLF_E);    /* set highlight for error messages */
  3996.     msg_add_fname(buf,
  3997. #ifndef UNIX
  3998.         sfname
  3999. #else
  4000.         fname
  4001. #endif
  4002.              );        /* put file name in IObuff with quotes */
  4003.     if (STRLEN(IObuff) + STRLEN(errmsg) + numlen >= IOSIZE)
  4004.         IObuff[IOSIZE - STRLEN(errmsg) - numlen - 1] = NUL;
  4005.     /* If the error message has the form "is ...", put the error number in
  4006.      * front of the file name. */
  4007.     if (errnum != NULL)
  4008.     {
  4009.         mch_memmove(IObuff + numlen, IObuff, STRLEN(IObuff) + 1);
  4010.         mch_memmove(IObuff, errnum, (size_t)numlen);
  4011.     }
  4012.     STRCAT(IObuff, errmsg);
  4013.     emsg(IObuff);
  4014.  
  4015.     retval = FAIL;
  4016.     if (end == 0)
  4017.     {
  4018.         MSG_PUTS_ATTR(_("\nWARNING: Original file may be lost or damaged\n"),
  4019.             attr | MSG_HIST);
  4020.         MSG_PUTS_ATTR(_("don't quit the editor until the file is successfully written!"),
  4021.             attr | MSG_HIST);
  4022.  
  4023.         /* Update the timestamp to avoid an "overwrite changed file"
  4024.          * prompt when writing again. */
  4025.         if (mch_stat((char *)fname, &st_old) >= 0)
  4026.         {
  4027.         buf_store_time(buf, &st_old, fname);
  4028.         buf->b_mtime_read = buf->b_mtime;
  4029.         }
  4030.     }
  4031.     }
  4032.     msg_scroll = msg_save;
  4033.  
  4034. #ifdef FEAT_AUTOCMD
  4035. #ifdef FEAT_EVAL
  4036.     if (!should_abort(retval))
  4037. #else
  4038.     if (!got_int)
  4039. #endif
  4040.     {
  4041.     aco_save_T    aco;
  4042.  
  4043.     write_no_eol_lnum = 0;    /* in case it was set by the previous read */
  4044.  
  4045.     /*
  4046.      * Apply POST autocommands.
  4047.      * Careful: The autocommands may call buf_write() recursively!
  4048.      */
  4049.     aucmd_prepbuf(&aco, buf);
  4050.  
  4051.     if (append)
  4052.         apply_autocmds_exarg(EVENT_FILEAPPENDPOST, fname, fname,
  4053.                               FALSE, curbuf, eap);
  4054.     else if (filtering)
  4055.         apply_autocmds_exarg(EVENT_FILTERWRITEPOST, NULL, fname,
  4056.                               FALSE, curbuf, eap);
  4057.     else if (reset_changed && whole)
  4058.         apply_autocmds_exarg(EVENT_BUFWRITEPOST, fname, fname,
  4059.                               FALSE, curbuf, eap);
  4060.     else
  4061.         apply_autocmds_exarg(EVENT_FILEWRITEPOST, fname, fname,
  4062.                               FALSE, curbuf, eap);
  4063.  
  4064.     /* restore curwin/curbuf and a few other things */
  4065.     aucmd_restbuf(&aco);
  4066.  
  4067. #ifdef FEAT_EVAL
  4068.     if (aborting())        /* autocmds may abort script processing */
  4069.         retval = FALSE;
  4070. #endif
  4071.     }
  4072. #endif
  4073.  
  4074.     got_int |= prev_got_int;
  4075.  
  4076. #ifdef MACOS_CLASSIC /* TODO: Is it need for MACOS_X? (Dany) */
  4077.     /* Update machine specific information. */
  4078.     mch_post_buffer_write(buf);
  4079. #endif
  4080.     return retval;
  4081. }
  4082.  
  4083. /*
  4084.  * Put file name into IObuff with quotes.
  4085.  */
  4086.     static void
  4087. msg_add_fname(buf, fname)
  4088.     buf_T    *buf;
  4089.     char_u    *fname;
  4090. {
  4091.     if (fname == NULL)
  4092.     fname = (char_u *)"-stdin-";
  4093.     home_replace(buf, fname, IObuff + 1, IOSIZE - 4, TRUE);
  4094.     IObuff[0] = '"';
  4095.     STRCAT(IObuff, "\" ");
  4096. }
  4097.  
  4098. /*
  4099.  * Append message for text mode to IObuff.
  4100.  * Return TRUE if something appended.
  4101.  */
  4102.     static int
  4103. msg_add_fileformat(eol_type)
  4104.     int        eol_type;
  4105. {
  4106. #ifndef USE_CRNL
  4107.     if (eol_type == EOL_DOS)
  4108.     {
  4109.     STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[dos]") : _("[dos format]"));
  4110.     return TRUE;
  4111.     }
  4112. #endif
  4113. #ifndef USE_CR
  4114.     if (eol_type == EOL_MAC)
  4115.     {
  4116.     STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[mac]") : _("[mac format]"));
  4117.     return TRUE;
  4118.     }
  4119. #endif
  4120. #if defined(USE_CRNL) || defined(USE_CR)
  4121.     if (eol_type == EOL_UNIX)
  4122.     {
  4123.     STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[unix]") : _("[unix format]"));
  4124.     return TRUE;
  4125.     }
  4126. #endif
  4127.     return FALSE;
  4128. }
  4129.  
  4130. /*
  4131.  * Append line and character count to IObuff.
  4132.  */
  4133.     static void
  4134. msg_add_lines(insert_space, lnum, nchars)
  4135.     int        insert_space;
  4136.     long    lnum;
  4137.     long    nchars;
  4138. {
  4139.     char_u  *p;
  4140.  
  4141.     p = IObuff + STRLEN(IObuff);
  4142.  
  4143.     if (insert_space)
  4144.     *p++ = ' ';
  4145.     if (shortmess(SHM_LINES))
  4146.     sprintf((char *)p, "%ldL, %ldC", lnum, nchars);
  4147.     else
  4148.     {
  4149.     if (lnum == 1)
  4150.         STRCPY(p, _("1 line, "));
  4151.     else
  4152.         sprintf((char *)p, _("%ld lines, "), lnum);
  4153.     p += STRLEN(p);
  4154.     if (nchars == 1)
  4155.         STRCPY(p, _("1 character"));
  4156.     else
  4157.         sprintf((char *)p, _("%ld characters"), nchars);
  4158.     }
  4159. }
  4160.  
  4161. /*
  4162.  * Append message for missing line separator to IObuff.
  4163.  */
  4164.     static void
  4165. msg_add_eol()
  4166. {
  4167.     STRCAT(IObuff, shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]"));
  4168. }
  4169.  
  4170. /*
  4171.  * Check modification time of file, before writing to it.
  4172.  * The size isn't checked, because using a tool like "gzip" takes care of
  4173.  * using the same timestamp but can't set the size.
  4174.  */
  4175.     static int
  4176. check_mtime(buf, st)
  4177.     buf_T        *buf;
  4178.     struct stat        *st;
  4179. {
  4180.     if (buf->b_mtime_read != 0
  4181.         && time_differs((long)st->st_mtime, buf->b_mtime_read))
  4182.     {
  4183.     msg_scroll = TRUE;        /* don't overwrite messages here */
  4184.     msg_silent = 0;            /* must give this prompt */
  4185.     /* don't use emsg() here, don't want to flush the buffers */
  4186.     MSG_ATTR(_("WARNING: The file has been changed since reading it!!!"),
  4187.                                hl_attr(HLF_E));
  4188.     if (ask_yesno((char_u *)_("Do you really want to write to it"),
  4189.                                  TRUE) == 'n')
  4190.         return FAIL;
  4191.     msg_scroll = FALSE;        /* always overwrite the file message now */
  4192.     }
  4193.     return OK;
  4194. }
  4195.  
  4196.     static int
  4197. time_differs(t1, t2)
  4198.     long    t1, t2;
  4199. {
  4200. #if defined(__linux__) || defined(MSDOS) || defined(MSWIN)
  4201.     /* On a FAT filesystem, esp. under Linux, there are only 5 bits to store
  4202.      * the seconds.  Since the roundoff is done when flushing the inode, the
  4203.      * time may change unexpectedly by one second!!! */
  4204.     return (t1 - t2 > 1 || t2 - t1 > 1);
  4205. #else
  4206.     return (t1 != t2);
  4207. #endif
  4208. }
  4209.  
  4210. /*
  4211.  * Call write() to write a number of bytes to the file.
  4212.  * Also handles encryption and 'encoding' conversion.
  4213.  *
  4214.  * Return FAIL for failure, OK otherwise.
  4215.  */
  4216.     static int
  4217. buf_write_bytes(ip)
  4218.     struct bw_info *ip;
  4219. {
  4220.     int        wlen;
  4221.     char_u    *buf = ip->bw_buf;    /* data to write */
  4222.     int        len = ip->bw_len;    /* length of data */
  4223. #ifdef HAS_BW_FLAGS
  4224.     int        flags = ip->bw_flags;    /* extra flags */
  4225. #endif
  4226.  
  4227. #ifdef FEAT_MBYTE
  4228.     /*
  4229.      * Skip conversion when writing the crypt magic number or the BOM.
  4230.      */
  4231.     if (!(flags & FIO_NOCONVERT))
  4232.     {
  4233.     char_u        *p;
  4234.     unsigned    c;
  4235.     int        n;
  4236.  
  4237.     if (flags & FIO_UTF8)
  4238.     {
  4239.         /*
  4240.          * Convert latin1 in the buffer to UTF-8 in the file.
  4241.          */
  4242.         p = ip->bw_conv_buf;    /* translate to buffer */
  4243.         for (wlen = 0; wlen < len; ++wlen)
  4244.         p += utf_char2bytes(buf[wlen], p);
  4245.         buf = ip->bw_conv_buf;
  4246.         len = (int)(p - ip->bw_conv_buf);
  4247.     }
  4248.     else if (flags & (FIO_UCS4 | FIO_UTF16 | FIO_UCS2 | FIO_LATIN1))
  4249.     {
  4250.         /*
  4251.          * Convert UTF-8 bytes in the buffer to UCS-2, UCS-4, UTF-16 or
  4252.          * Latin1 chars in the file.
  4253.          */
  4254.         if (flags & FIO_LATIN1)
  4255.         p = buf;    /* translate in-place (can only get shorter) */
  4256.         else
  4257.         p = ip->bw_conv_buf;    /* translate to buffer */
  4258.         for (wlen = 0; wlen < len; wlen += n)
  4259.         {
  4260.         if (wlen == 0 && ip->bw_restlen != 0)
  4261.         {
  4262.             int        l;
  4263.  
  4264.             /* Use remainder of previous call.  Append the start of
  4265.              * buf[] to get a full sequence.  Might still be too
  4266.              * short! */
  4267.             l = CONV_RESTLEN - ip->bw_restlen;
  4268.             if (l > len)
  4269.             l = len;
  4270.             mch_memmove(ip->bw_rest + ip->bw_restlen, buf, (size_t)l);
  4271.             n = utf_ptr2len_check_len(ip->bw_rest, ip->bw_restlen + l);
  4272.             if (n > ip->bw_restlen + len)
  4273.             {
  4274.             /* We have an incomplete byte sequence at the end to
  4275.              * be written.  We can't convert it without the
  4276.              * remaining bytes.  Keep them for the next call. */
  4277.             if (ip->bw_restlen + len > CONV_RESTLEN)
  4278.                 return FAIL;
  4279.             ip->bw_restlen += len;
  4280.             break;
  4281.             }
  4282.             if (n > 1)
  4283.             c = utf_ptr2char(ip->bw_rest);
  4284.             else
  4285.             c = ip->bw_rest[0];
  4286.             if (n >= ip->bw_restlen)
  4287.             {
  4288.             n -= ip->bw_restlen;
  4289.             ip->bw_restlen = 0;
  4290.             }
  4291.             else
  4292.             {
  4293.             ip->bw_restlen -= n;
  4294.             mch_memmove(ip->bw_rest, ip->bw_rest + n,
  4295.                               (size_t)ip->bw_restlen);
  4296.             n = 0;
  4297.             }
  4298.         }
  4299.         else
  4300.         {
  4301.             n = utf_ptr2len_check_len(buf + wlen, len - wlen);
  4302.             if (n > len - wlen)
  4303.             {
  4304.             /* We have an incomplete byte sequence at the end to
  4305.              * be written.  We can't convert it without the
  4306.              * remaining bytes.  Keep them for the next call. */
  4307.             if (len - wlen > CONV_RESTLEN)
  4308.                 return FAIL;
  4309.             ip->bw_restlen = len - wlen;
  4310.             mch_memmove(ip->bw_rest, buf + wlen,
  4311.                               (size_t)ip->bw_restlen);
  4312.             break;
  4313.             }
  4314.             if (n > 1)
  4315.             c = utf_ptr2char(buf + wlen);
  4316.             else
  4317.             c = buf[wlen];
  4318.         }
  4319.  
  4320.         ip->bw_conv_error |= ucs2bytes(c, &p, flags);
  4321.         }
  4322.         if (flags & FIO_LATIN1)
  4323.         len = (int)(p - buf);
  4324.         else
  4325.         {
  4326.         buf = ip->bw_conv_buf;
  4327.         len = (int)(p - ip->bw_conv_buf);
  4328.         }
  4329.     }
  4330.  
  4331. # ifdef WIN3264
  4332.     else if (flags & FIO_CODEPAGE)
  4333.     {
  4334.         /*
  4335.          * Convert UTF-8 to UCS-2 and then to MS-Windows codepage.
  4336.          */
  4337.         char_u    *from;
  4338.         size_t    fromlen;
  4339.         char_u    *to;
  4340.         int        u8c;
  4341.         BOOL    bad = FALSE;
  4342.  
  4343.         if (ip->bw_restlen > 0)
  4344.         {
  4345.         /* Need to concatenate the remainder of the previous call and
  4346.          * the bytes of the current call.  Use the end of the
  4347.          * conversion buffer for this. */
  4348.         fromlen = len + ip->bw_restlen;
  4349.         from = ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
  4350.         mch_memmove(from, ip->bw_rest, (size_t)ip->bw_restlen);
  4351.         mch_memmove(from + ip->bw_restlen, buf, (size_t)len);
  4352.         }
  4353.         else
  4354.         {
  4355.         from = buf;
  4356.         fromlen = len;
  4357.         }
  4358.  
  4359.         /* Convert from UTF-8 to UCS-2, to the start of the buffer.
  4360.          * The buffer has been allocated to be big enough. */
  4361.         to = ip->bw_conv_buf;
  4362.         while (fromlen > 0)
  4363.         {
  4364.         n = utf_ptr2len_check_len(from, fromlen);
  4365.         if (n > (int)fromlen)
  4366.             break;
  4367.         u8c = utf_ptr2char(from);
  4368.         *to++ = (u8c & 0xff);
  4369.         *to++ = (u8c >> 8);
  4370.         fromlen -= n;
  4371.         from += n;
  4372.         }
  4373.  
  4374.         /* copy remainder to ip->bw_rest[] to be used for the next call. */
  4375.         mch_memmove(ip->bw_rest, from, fromlen);
  4376.         ip->bw_restlen = fromlen;
  4377.  
  4378.         /* Convert from UCS-2 to the codepage, using the remainder of the
  4379.          * conversion buffer.  If the conversion uses the default
  4380.          * character "0", the data doesn't fit in this encoding, so fail. */
  4381.         fromlen = to - ip->bw_conv_buf;
  4382.         len = WideCharToMultiByte(FIO_GET_CP(flags), 0,
  4383.             (LPCWSTR)ip->bw_conv_buf, (int)fromlen / sizeof(WCHAR),
  4384.             (LPSTR)to, ip->bw_conv_buflen - fromlen, 0, &bad);
  4385.         if (bad)
  4386.         {
  4387.         ip->bw_conv_error = TRUE;
  4388.         return FAIL;
  4389.         }
  4390.         buf = to;
  4391.     }
  4392. # endif
  4393.  
  4394. # ifdef USE_ICONV
  4395.     if (ip->bw_iconv_fd != (iconv_t)-1)
  4396.     {
  4397.         const char    *from;
  4398.         size_t    fromlen;
  4399.         char    *to;
  4400.         size_t    tolen;
  4401.  
  4402.         /* Convert with iconv(). */
  4403.         if (ip->bw_restlen > 0)
  4404.         {
  4405.         /* Need to concatenate the remainder of the previous call and
  4406.          * the bytes of the current call.  Use the end of the
  4407.          * conversion buffer for this. */
  4408.         fromlen = len + ip->bw_restlen;
  4409.         from = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
  4410.         mch_memmove((void *)from, ip->bw_rest, (size_t)ip->bw_restlen);
  4411.         mch_memmove((void *)(from + ip->bw_restlen), buf, (size_t)len);
  4412.         tolen = ip->bw_conv_buflen - fromlen;
  4413.         }
  4414.         else
  4415.         {
  4416.         from = (const char *)buf;
  4417.         fromlen = len;
  4418.         tolen = ip->bw_conv_buflen;
  4419.         }
  4420.         to = (char *)ip->bw_conv_buf;
  4421.  
  4422.         if (ip->bw_first)
  4423.         {
  4424.         size_t    save_len = tolen;
  4425.  
  4426.         /* output the initial shift state sequence */
  4427.         (void)iconv(ip->bw_iconv_fd, NULL, NULL, &to, &tolen);
  4428.  
  4429.         /* There is a bug in iconv() on Linux (which appears to be
  4430.          * wide-spread) which sets "to" to NULL and messes up "tolen".
  4431.          */
  4432.         if (to == NULL)
  4433.         {
  4434.             to = (char *)ip->bw_conv_buf;
  4435.             tolen = save_len;
  4436.         }
  4437.         ip->bw_first = FALSE;
  4438.         }
  4439.  
  4440.         /*
  4441.          * If iconv() has an error or there is not enough room, fail.
  4442.          */
  4443.         if ((iconv(ip->bw_iconv_fd, &from, &fromlen, &to, &tolen)
  4444.             == (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL)
  4445.                             || fromlen > CONV_RESTLEN)
  4446.         {
  4447.         ip->bw_conv_error = TRUE;
  4448.         return FAIL;
  4449.         }
  4450.  
  4451.         /* copy remainder to ip->bw_rest[] to be used for the next call. */
  4452.         if (fromlen > 0)
  4453.         mch_memmove(ip->bw_rest, (void *)from, fromlen);
  4454.         ip->bw_restlen = (int)fromlen;
  4455.  
  4456.         buf = ip->bw_conv_buf;
  4457.         len = (int)((char_u *)to - ip->bw_conv_buf);
  4458.     }
  4459. # endif
  4460.     }
  4461. #endif /* FEAT_MBYTE */
  4462.  
  4463. #ifdef FEAT_CRYPT
  4464.     if (flags & FIO_ENCRYPTED)        /* encrypt the data */
  4465.     {
  4466.     int ztemp, t, i;
  4467.  
  4468.     for (i = 0; i < len; i++)
  4469.     {
  4470.         ztemp  = buf[i];
  4471.         buf[i] = ZENCODE(ztemp, t);
  4472.     }
  4473.     }
  4474. #endif
  4475.  
  4476.     /* Repeat the write(), it may be interrupted by a signal. */
  4477.     while (len)
  4478.     {
  4479.     wlen = vim_write(ip->bw_fd, buf, len);
  4480.     if (wlen <= 0)            /* error! */
  4481.         return FAIL;
  4482.     len -= wlen;
  4483.     buf += wlen;
  4484.     }
  4485.     return OK;
  4486. }
  4487.  
  4488. #ifdef FEAT_MBYTE
  4489. /*
  4490.  * Convert a Unicode character to bytes.
  4491.  */
  4492.     static int
  4493. ucs2bytes(c, pp, flags)
  4494.     unsigned    c;        /* in: character */
  4495.     char_u    **pp;        /* in/out: pointer to result */
  4496.     int        flags;        /* FIO_ flags */
  4497. {
  4498.     char_u    *p = *pp;
  4499.     int        error = FALSE;
  4500.     int        cc;
  4501.  
  4502.  
  4503.     if (flags & FIO_UCS4)
  4504.     {
  4505.     if (flags & FIO_ENDIAN_L)
  4506.     {
  4507.         *p++ = c;
  4508.         *p++ = (c >> 8);
  4509.         *p++ = (c >> 16);
  4510.         *p++ = (c >> 24);
  4511.     }
  4512.     else
  4513.     {
  4514.         *p++ = (c >> 24);
  4515.         *p++ = (c >> 16);
  4516.         *p++ = (c >> 8);
  4517.         *p++ = c;
  4518.     }
  4519.     }
  4520.     else if (flags & (FIO_UCS2 | FIO_UTF16))
  4521.     {
  4522.     if (c >= 0x10000)
  4523.     {
  4524.         if (flags & FIO_UTF16)
  4525.         {
  4526.         /* Make two words, ten bits of the character in each.  First
  4527.          * word is 0xd800 - 0xdbff, second one 0xdc00 - 0xdfff */
  4528.         c -= 0x10000;
  4529.         if (c >= 0x100000)
  4530.             error = TRUE;
  4531.         cc = ((c >> 10) & 0x3ff) + 0xd800;
  4532.         if (flags & FIO_ENDIAN_L)
  4533.         {
  4534.             *p++ = cc;
  4535.             *p++ = ((unsigned)cc >> 8);
  4536.         }
  4537.         else
  4538.         {
  4539.             *p++ = ((unsigned)cc >> 8);
  4540.             *p++ = cc;
  4541.         }
  4542.         c = (c & 0x3ff) + 0xdc00;
  4543.         }
  4544.         else
  4545.         error = TRUE;
  4546.     }
  4547.     if (flags & FIO_ENDIAN_L)
  4548.     {
  4549.         *p++ = c;
  4550.         *p++ = (c >> 8);
  4551.     }
  4552.     else
  4553.     {
  4554.         *p++ = (c >> 8);
  4555.         *p++ = c;
  4556.     }
  4557.     }
  4558.     else    /* Latin1 */
  4559.     {
  4560.     if (c >= 0x100)
  4561.     {
  4562.         error = TRUE;
  4563.         *p++ = 0xBF;
  4564.     }
  4565.     else
  4566.         *p++ = c;
  4567.     }
  4568.  
  4569.     *pp = p;
  4570.     return error;
  4571. }
  4572.  
  4573. /*
  4574.  * Return TRUE if "a" and "b" are the same 'encoding'.
  4575.  * Ignores difference between "ansi" and "latin1", "ucs-4" and "ucs-4be", etc.
  4576.  */
  4577.     static int
  4578. same_encoding(a, b)
  4579.     char_u    *a;
  4580.     char_u    *b;
  4581. {
  4582.     int        f;
  4583.  
  4584.     if (STRCMP(a, b) == 0)
  4585.     return TRUE;
  4586.     f = get_fio_flags(a);
  4587.     return (f != 0 && get_fio_flags(b) == f);
  4588. }
  4589.  
  4590. /*
  4591.  * Check "ptr" for a unicode encoding and return the FIO_ flags needed for the
  4592.  * internal conversion.
  4593.  * if "ptr" is an empty string, use 'encoding'.
  4594.  */
  4595.     static int
  4596. get_fio_flags(ptr)
  4597.     char_u    *ptr;
  4598. {
  4599.     int        prop;
  4600.  
  4601.     if (*ptr == NUL)
  4602.     ptr = p_enc;
  4603.  
  4604.     prop = enc_canon_props(ptr);
  4605.     if (prop & ENC_UNICODE)
  4606.     {
  4607.     if (prop & ENC_2BYTE)
  4608.     {
  4609.         if (prop & ENC_ENDIAN_L)
  4610.         return FIO_UCS2 | FIO_ENDIAN_L;
  4611.         return FIO_UCS2;
  4612.     }
  4613.     if (prop & ENC_4BYTE)
  4614.     {
  4615.         if (prop & ENC_ENDIAN_L)
  4616.         return FIO_UCS4 | FIO_ENDIAN_L;
  4617.         return FIO_UCS4;
  4618.     }
  4619.     if (prop & ENC_2WORD)
  4620.     {
  4621.         if (prop & ENC_ENDIAN_L)
  4622.         return FIO_UTF16 | FIO_ENDIAN_L;
  4623.         return FIO_UTF16;
  4624.     }
  4625.     return FIO_UTF8;
  4626.     }
  4627.     if (prop & ENC_LATIN1)
  4628.     return FIO_LATIN1;
  4629.     /* must be ENC_DBCS, requires iconv() */
  4630.     return 0;
  4631. }
  4632.  
  4633. #ifdef WIN3264
  4634. /*
  4635.  * Check "ptr" for a MS-Windows codepage name and return the FIO_ flags needed
  4636.  * for the conversion MS-Windows can do for us.
  4637.  */
  4638.     static int
  4639. get_win_fio_flags(ptr)
  4640.     char_u    *ptr;
  4641. {
  4642.     if (ptr[0] == 'c' && ptr[1] == 'p' && isdigit(ptr[2]))
  4643.     return FIO_PUT_CP(atoi(ptr + 2)) | FIO_CODEPAGE;
  4644.     return 0;
  4645. }
  4646. #endif
  4647.  
  4648. /*
  4649.  * Check for a Unicode BOM (Byte Order Mark) at the start of p[size].
  4650.  * "size" must be at least 2.
  4651.  * Return the name of the encoding and set "*lenp" to the length.
  4652.  * Returns NULL when no BOM found.
  4653.  */
  4654.     static char_u *
  4655. check_for_bom(p, size, lenp, flags)
  4656.     char_u    *p;
  4657.     long    size;
  4658.     int        *lenp;
  4659.     int        flags;
  4660. {
  4661.     char    *name = NULL;
  4662.     int        len = 2;
  4663.  
  4664.     if (p[0] == 0xef && p[1] == 0xbb && size >= 3 && p[2] == 0xbf
  4665.         && (flags == FIO_ALL || flags == 0))
  4666.     {
  4667.     name = "utf-8";        /* EF BB BF */
  4668.     len = 3;
  4669.     }
  4670.     else if (p[0] == 0xff && p[1] == 0xfe)
  4671.     {
  4672.     if (size >= 4 && p[2] == 0 && p[3] == 0
  4673.         && (flags == FIO_ALL || flags == (FIO_UCS4 | FIO_ENDIAN_L)))
  4674.     {
  4675.         name = "ucs-4le";    /* FF FE 00 00 */
  4676.         len = 4;
  4677.     }
  4678.     else if (flags == FIO_ALL || flags == (FIO_UCS2 | FIO_ENDIAN_L))
  4679.         name = "ucs-2le";    /* FF FE */
  4680.     else if (flags == (FIO_UTF16 | FIO_ENDIAN_L))
  4681.         name = "utf-16le";    /* FF FE */
  4682.     }
  4683.     else if (p[0] == 0xfe && p[1] == 0xff
  4684.         && (flags == FIO_ALL || flags == FIO_UCS2 || flags == FIO_UTF16))
  4685.     {
  4686.     if (flags == FIO_UTF16)
  4687.         name = "utf-16";    /* FE FF */
  4688.     else
  4689.         name = "ucs-2";    /* FE FF */
  4690.     }
  4691.     else if (size >= 4 && p[0] == 0 && p[1] == 0 && p[2] == 0xfe
  4692.         && p[3] == 0xff && (flags == FIO_ALL || flags == FIO_UCS4))
  4693.     {
  4694.     name = "ucs-4";        /* 00 00 FE FF */
  4695.     len = 4;
  4696.     }
  4697.  
  4698.     *lenp = len;
  4699.     return (char_u *)name;
  4700. }
  4701.  
  4702. /*
  4703.  * Generate a BOM in "buf[4]" for encoding "name".
  4704.  * Return the length of the BOM (zero when no BOM).
  4705.  */
  4706.     static int
  4707. make_bom(buf, name)
  4708.     char_u    *buf;
  4709.     char_u    *name;
  4710. {
  4711.     int        flags;
  4712.     char_u    *p;
  4713.  
  4714.     flags = get_fio_flags(name);
  4715.  
  4716.     /* Can't put a BOM in a non-Unicode file. */
  4717.     if (flags == FIO_LATIN1 || flags == 0)
  4718.     return 0;
  4719.  
  4720.     if (flags == FIO_UTF8)    /* UTF-8 */
  4721.     {
  4722.     buf[0] = 0xef;
  4723.     buf[1] = 0xbb;
  4724.     buf[2] = 0xbf;
  4725.     return 3;
  4726.     }
  4727.     p = buf;
  4728.     (void)ucs2bytes(0xfeff, &p, flags);
  4729.     return (int)(p - buf);
  4730. }
  4731. #endif
  4732.  
  4733. /*
  4734.  * Try to find a shortname by comparing the fullname with the current
  4735.  * directory.
  4736.  * Returns NULL if not shorter name possible, pointer into "full_path"
  4737.  * otherwise.
  4738.  */
  4739.     char_u *
  4740. shorten_fname(full_path, dir_name)
  4741.     char_u    *full_path;
  4742.     char_u    *dir_name;
  4743. {
  4744.     int        len;
  4745.     char_u    *p;
  4746.  
  4747.     if (full_path == NULL)
  4748.     return NULL;
  4749.     len = (int)STRLEN(dir_name);
  4750.     if (fnamencmp(dir_name, full_path, len) == 0)
  4751.     {
  4752.     p = full_path + len;
  4753. #if defined(MSDOS) || defined(MSWIN) || defined(OS2)
  4754.     /*
  4755.      * MSDOS: when a file is in the root directory, dir_name will end in a
  4756.      * slash, since C: by itself does not define a specific dir. In this
  4757.      * case p may already be correct. <negri>
  4758.      */
  4759.     if (!((len > 2) && (*(p - 2) == ':')))
  4760. #endif
  4761.     {
  4762.         if (vim_ispathsep(*p))
  4763.         ++p;
  4764. #ifndef VMS   /* the path separator is always part of the path */
  4765.         else
  4766.         p = NULL;
  4767. #endif
  4768.     }
  4769.     }
  4770. #if defined(MSDOS) || defined(MSWIN) || defined(OS2)
  4771.     /*
  4772.      * When using a file in the current drive, remove the drive name:
  4773.      * "A:\dir\file" -> "\dir\file".  This helps when moving a session file on
  4774.      * a floppy from "A:\dir" to "B:\dir".
  4775.      */
  4776.     else if (len > 3
  4777.         && TOUPPER_LOC(full_path[0]) == TOUPPER_LOC(dir_name[0])
  4778.         && full_path[1] == ':'
  4779.         && vim_ispathsep(full_path[2]))
  4780.     p = full_path + 2;
  4781. #endif
  4782.     else
  4783.     p = NULL;
  4784.     return p;
  4785. }
  4786.  
  4787. /*
  4788.  * When "force" is TRUE: Use full path from now on for files currently being
  4789.  * edited, both for file name and swap file name.  Try to shorten the file
  4790.  * names a bit, if safe to do so.
  4791.  * When "force" is FALSE: Only try to shorten absolute file names.
  4792.  * For buffers that have buftype "nofile" or "scratch": never change the file
  4793.  * name.
  4794.  */
  4795.     void
  4796. shorten_fnames(force)
  4797.     int        force;
  4798. {
  4799.     char_u    dirname[MAXPATHL];
  4800.     buf_T    *buf;
  4801.     char_u    *p;
  4802.  
  4803.     mch_dirname(dirname, MAXPATHL);
  4804.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  4805.     {
  4806.     if (buf->b_fname != NULL
  4807. #ifdef FEAT_QUICKFIX
  4808.         && !bt_nofile(buf)
  4809. #endif
  4810.         && !path_with_url(buf->b_fname)
  4811.         && (force
  4812.             || buf->b_sfname == NULL
  4813.             || mch_isFullName(buf->b_sfname)))
  4814.     {
  4815.         vim_free(buf->b_sfname);
  4816.         buf->b_sfname = NULL;
  4817.         p = shorten_fname(buf->b_ffname, dirname);
  4818.         if (p != NULL)
  4819.         {
  4820.         buf->b_sfname = vim_strsave(p);
  4821.         buf->b_fname = buf->b_sfname;
  4822.         }
  4823.         if (p == NULL || buf->b_fname == NULL)
  4824.         buf->b_fname = buf->b_ffname;
  4825.         mf_fullname(buf->b_ml.ml_mfp);
  4826.     }
  4827.     }
  4828. #ifdef FEAT_WINDOWS
  4829.     status_redraw_all();
  4830. #endif
  4831. }
  4832.  
  4833. /*
  4834.  * add extention to file name - change path/fo.o.h to path/fo.o.h.ext or
  4835.  * fo_o_h.ext for MSDOS or when shortname option set.
  4836.  *
  4837.  * Assumed that fname is a valid name found in the filesystem we assure that
  4838.  * the return value is a different name and ends in 'ext'.
  4839.  * "ext" MUST be at most 4 characters long if it starts with a dot, 3
  4840.  * characters otherwise.
  4841.  * Space for the returned name is allocated, must be freed later.
  4842.  * Returns NULL when out of memory.
  4843.  */
  4844.     char_u *
  4845. modname(fname, ext, prepend_dot)
  4846.     char_u *fname, *ext;
  4847.     int        prepend_dot;    /* may prepend a '.' to file name */
  4848. {
  4849.     return buf_modname(
  4850. #ifdef SHORT_FNAME
  4851.             TRUE,
  4852. #else
  4853.             (curbuf->b_p_sn || curbuf->b_shortname),
  4854. #endif
  4855.                              fname, ext, prepend_dot);
  4856. }
  4857.  
  4858.     char_u *
  4859. buf_modname(shortname, fname, ext, prepend_dot)
  4860.     int        shortname;        /* use 8.3 file name */
  4861.     char_u  *fname, *ext;
  4862.     int        prepend_dot;    /* may prepend a '.' to file name */
  4863. {
  4864.     char_u    *retval;
  4865.     char_u    *s;
  4866.     char_u    *e;
  4867.     char_u    *ptr;
  4868.     int        fnamelen, extlen;
  4869.  
  4870.     extlen = (int)STRLEN(ext);
  4871.  
  4872.     /*
  4873.      * If there is no file name we must get the name of the current directory
  4874.      * (we need the full path in case :cd is used).
  4875.      */
  4876.     if (fname == NULL || *fname == NUL)
  4877.     {
  4878.     retval = alloc((unsigned)(MAXPATHL + extlen + 3));
  4879.     if (retval == NULL)
  4880.         return NULL;
  4881.     if (mch_dirname(retval, MAXPATHL) == FAIL ||
  4882.                      (fnamelen = (int)STRLEN(retval)) == 0)
  4883.     {
  4884.         vim_free(retval);
  4885.         return NULL;
  4886.     }
  4887.     if (!vim_ispathsep(retval[fnamelen - 1]))
  4888.     {
  4889.         retval[fnamelen++] = PATHSEP;
  4890.         retval[fnamelen] = NUL;
  4891.     }
  4892. #ifndef SHORT_FNAME
  4893.     prepend_dot = FALSE;        /* nothing to prepend a dot to */
  4894. #endif
  4895.     }
  4896.     else
  4897.     {
  4898.     fnamelen = (int)STRLEN(fname);
  4899.     retval = alloc((unsigned)(fnamelen + extlen + 3));
  4900.     if (retval == NULL)
  4901.         return NULL;
  4902.     STRCPY(retval, fname);
  4903. #ifdef VMS
  4904.     vms_remove_version(retval); /* we do not need versions here */
  4905. #endif
  4906.     }
  4907.  
  4908.     /*
  4909.      * search backwards until we hit a '/', '\' or ':' replacing all '.'
  4910.      * by '_' for MSDOS or when shortname option set and ext starts with a dot.
  4911.      * Then truncate what is after the '/', '\' or ':' to 8 characters for
  4912.      * MSDOS and 26 characters for AMIGA, a lot more for UNIX.
  4913.      */
  4914.     for (ptr = retval + fnamelen; ptr >= retval; ptr--)
  4915.     {
  4916. #ifndef RISCOS
  4917.     if (*ext == '.'
  4918. #ifdef USE_LONG_FNAME
  4919.             && (!USE_LONG_FNAME || shortname)
  4920. #else
  4921. # ifndef SHORT_FNAME
  4922.             && shortname
  4923. # endif
  4924. #endif
  4925.                                 )
  4926.         if (*ptr == '.')    /* replace '.' by '_' */
  4927.         *ptr = '_';
  4928. #endif /* RISCOS */
  4929.     if (vim_ispathsep(*ptr))
  4930.         break;
  4931.     }
  4932.     ptr++;
  4933.  
  4934.     /* the file name has at most BASENAMELEN characters. */
  4935. #ifndef SHORT_FNAME
  4936.     if (STRLEN(ptr) > (unsigned)BASENAMELEN)
  4937.     ptr[BASENAMELEN] = '\0';
  4938. #endif
  4939.  
  4940.     s = ptr + STRLEN(ptr);
  4941.  
  4942.     /*
  4943.      * For 8.3 file names we may have to reduce the length.
  4944.      */
  4945. #ifdef USE_LONG_FNAME
  4946.     if (!USE_LONG_FNAME || shortname)
  4947. #else
  4948. # ifndef SHORT_FNAME
  4949.     if (shortname)
  4950. # endif
  4951. #endif
  4952.     {
  4953.     /*
  4954.      * If there is no file name, or the file name ends in '/', and the
  4955.      * extension starts with '.', put a '_' before the dot, because just
  4956.      * ".ext" is invalid.
  4957.      */
  4958.     if (fname == NULL || *fname == NUL
  4959.                    || vim_ispathsep(fname[STRLEN(fname) - 1]))
  4960.     {
  4961. #ifdef RISCOS
  4962.         if (*ext == '/')
  4963. #else
  4964.         if (*ext == '.')
  4965. #endif
  4966.         *s++ = '_';
  4967.     }
  4968.     /*
  4969.      * If the extension starts with '.', truncate the base name at 8
  4970.      * characters
  4971.      */
  4972. #ifdef RISCOS
  4973.     /* We normally use '/', but swap files are '_' */
  4974.     else if (*ext == '/' || *ext == '_')
  4975. #else
  4976.     else if (*ext == '.')
  4977. #endif
  4978.     {
  4979.         if (s - ptr > (size_t)8)
  4980.         {
  4981.         s = ptr + 8;
  4982.         *s = '\0';
  4983.         }
  4984.     }
  4985.     /*
  4986.      * If the extension doesn't start with '.', and the file name
  4987.      * doesn't have an extension yet, append a '.'
  4988.      */
  4989. #ifdef RISCOS
  4990.     else if ((e = vim_strchr(ptr, '/')) == NULL)
  4991.         *s++ = '/';
  4992. #else
  4993.     else if ((e = vim_strchr(ptr, '.')) == NULL)
  4994.         *s++ = '.';
  4995. #endif
  4996.     /*
  4997.      * If the extension doesn't start with '.', and there already is an
  4998.      * extension, it may need to be tructated
  4999.      */
  5000.     else if ((int)STRLEN(e) + extlen > 4)
  5001.         s = e + 4 - extlen;
  5002.     }
  5003. #if defined(OS2) || defined(USE_LONG_FNAME) || defined(WIN3264)
  5004.     /*
  5005.      * If there is no file name, and the extension starts with '.', put a
  5006.      * '_' before the dot, because just ".ext" may be invalid if it's on a
  5007.      * FAT partition, and on HPFS it doesn't matter.
  5008.      */
  5009.     else if ((fname == NULL || *fname == NUL) && *ext == '.')
  5010.     *s++ = '_';
  5011. #endif
  5012.  
  5013.     /*
  5014.      * Append the extention.
  5015.      * ext can start with '.' and cannot exceed 3 more characters.
  5016.      */
  5017.     STRCPY(s, ext);
  5018.  
  5019. #ifndef SHORT_FNAME
  5020.     /*
  5021.      * Prepend the dot.
  5022.      */
  5023.     if (prepend_dot && !shortname && *(e = gettail(retval)) !=
  5024. #ifdef RISCOS
  5025.         '/'
  5026. #else
  5027.         '.'
  5028. #endif
  5029. #ifdef USE_LONG_FNAME
  5030.         && USE_LONG_FNAME
  5031. #endif
  5032.                 )
  5033.     {
  5034.     mch_memmove(e + 1, e, STRLEN(e) + 1);
  5035. #ifdef RISCOS
  5036.     *e = '/';
  5037. #else
  5038.     *e = '.';
  5039. #endif
  5040.     }
  5041. #endif
  5042.  
  5043.     /*
  5044.      * Check that, after appending the extension, the file name is really
  5045.      * different.
  5046.      */
  5047.     if (fname != NULL && STRCMP(fname, retval) == 0)
  5048.     {
  5049.     /* we search for a character that can be replaced by '_' */
  5050.     while (--s >= ptr)
  5051.     {
  5052.         if (*s != '_')
  5053.         {
  5054.         *s = '_';
  5055.         break;
  5056.         }
  5057.     }
  5058.     if (s < ptr)    /* fname was "________.<ext>", how tricky! */
  5059.         *ptr = 'v';
  5060.     }
  5061.     return retval;
  5062. }
  5063.  
  5064. /*
  5065.  * Like fgets(), but if the file line is too long, it is truncated and the
  5066.  * rest of the line is thrown away.  Returns TRUE for end-of-file.
  5067.  */
  5068.     int
  5069. vim_fgets(buf, size, fp)
  5070.     char_u    *buf;
  5071.     int        size;
  5072.     FILE    *fp;
  5073. {
  5074.     char    *eof;
  5075. #define FGETS_SIZE 200
  5076.     char    tbuf[FGETS_SIZE];
  5077.  
  5078.     buf[size - 2] = NUL;
  5079. #ifdef USE_CR
  5080.     eof = fgets_cr((char *)buf, size, fp);
  5081. #else
  5082.     eof = fgets((char *)buf, size, fp);
  5083. #endif
  5084.     if (buf[size - 2] != NUL && buf[size - 2] != '\n')
  5085.     {
  5086.     buf[size - 1] = NUL;        /* Truncate the line */
  5087.  
  5088.     /* Now throw away the rest of the line: */
  5089.     do
  5090.     {
  5091.         tbuf[FGETS_SIZE - 2] = NUL;
  5092. #ifdef USE_CR
  5093.         fgets_cr((char *)tbuf, FGETS_SIZE, fp);
  5094. #else
  5095.         fgets((char *)tbuf, FGETS_SIZE, fp);
  5096. #endif
  5097.     } while (tbuf[FGETS_SIZE - 2] != NUL && tbuf[FGETS_SIZE - 2] != '\n');
  5098.     }
  5099.     return (eof == NULL);
  5100. }
  5101.  
  5102. #if defined(USE_CR) || defined(PROTO)
  5103. /*
  5104.  * Like vim_fgets(), but accept any line terminator: CR, CR-LF or LF.
  5105.  * Returns TRUE for end-of-file.
  5106.  * Only used for the Mac, because it's much slower than vim_fgets().
  5107.  */
  5108.     int
  5109. tag_fgets(buf, size, fp)
  5110.     char_u    *buf;
  5111.     int        size;
  5112.     FILE    *fp;
  5113. {
  5114.     int        i = 0;
  5115.     int        c;
  5116.     int        eof = FALSE;
  5117.  
  5118.     for (;;)
  5119.     {
  5120.     c = fgetc(fp);
  5121.     if (c == EOF)
  5122.     {
  5123.         eof = TRUE;
  5124.         break;
  5125.     }
  5126.     if (c == '\r')
  5127.     {
  5128.         /* Always store a NL for end-of-line. */
  5129.         if (i < size - 1)
  5130.         buf[i++] = '\n';
  5131.         c = fgetc(fp);
  5132.         if (c != '\n')    /* Macintosh format: single CR. */
  5133.         ungetc(c, fp);
  5134.         break;
  5135.     }
  5136.     if (i < size - 1)
  5137.         buf[i++] = c;
  5138.     if (c == '\n')
  5139.         break;
  5140.     }
  5141.     buf[i] = NUL;
  5142.     return eof;
  5143. }
  5144. #endif
  5145.  
  5146. /*
  5147.  * rename() only works if both files are on the same file system, this
  5148.  * function will (attempts to?) copy the file across if rename fails -- webb
  5149.  * Return -1 for failure, 0 for success.
  5150.  */
  5151.     int
  5152. vim_rename(from, to)
  5153.     char_u    *from;
  5154.     char_u    *to;
  5155. {
  5156.     int        fd_in;
  5157.     int        fd_out;
  5158.     int        n;
  5159.     char    *errmsg = NULL;
  5160.     char    *buffer;
  5161. #ifdef AMIGA
  5162.     BPTR    flock;
  5163. #endif
  5164.  
  5165.     /*
  5166.      * When the names are identical, there is nothing to do.
  5167.      */
  5168.     if (fnamecmp(from, to) == 0)
  5169.     return 0;
  5170.  
  5171.     /*
  5172.      * First delete the "to" file, this is required on some systems to make
  5173.      * the mch_rename() work, on other systems it makes sure that we don't
  5174.      * have two files when the mch_rename() fails.
  5175.      */
  5176.  
  5177. #ifdef AMIGA
  5178.     /*
  5179.      * With MSDOS-compatible filesystems (crossdos, messydos) it is possible
  5180.      * that the name of the "to" file is the same as the "from" file, even
  5181.      * though the names are different. To avoid the chance of accidently
  5182.      * deleting the "from" file (horror!) we lock it during the remove.
  5183.      *
  5184.      * When used for making a backup before writing the file: This should not
  5185.      * happen with ":w", because startscript() should detect this problem and
  5186.      * set buf->b_shortname, causing modname() to return a correct ".bak" file
  5187.      * name.  This problem does exist with ":w filename", but then the
  5188.      * original file will be somewhere else so the backup isn't really
  5189.      * important. If autoscripting is off the rename may fail.
  5190.      */
  5191.     flock = Lock((UBYTE *)from, (long)ACCESS_READ);
  5192. #endif
  5193.     mch_remove(to);
  5194. #ifdef AMIGA
  5195.     if (flock)
  5196.     UnLock(flock);
  5197. #endif
  5198.  
  5199.     /*
  5200.      * First try a normal rename, return if it works.
  5201.      */
  5202.     if (mch_rename((char *)from, (char *)to) == 0)
  5203.     return 0;
  5204.  
  5205.     /*
  5206.      * Rename() failed, try copying the file.
  5207.      */
  5208.     fd_in = mch_open((char *)from, O_RDONLY|O_EXTRA, 0);
  5209.     if (fd_in == -1)
  5210.     return -1;
  5211.     fd_out = mch_open((char *)to, O_CREAT|O_EXCL|O_WRONLY|O_EXTRA, 0666);
  5212.     if (fd_out == -1)
  5213.     {
  5214.     close(fd_in);
  5215.     return -1;
  5216.     }
  5217.  
  5218.     buffer = (char *)alloc(BUFSIZE);
  5219.     if (buffer == NULL)
  5220.     {
  5221.     close(fd_in);
  5222.     close(fd_out);
  5223.     return -1;
  5224.     }
  5225.  
  5226.     while ((n = vim_read(fd_in, buffer, BUFSIZE)) > 0)
  5227.     if (vim_write(fd_out, buffer, n) != n)
  5228.     {
  5229.         errmsg = _("E208: Error writing to \"%s\"");
  5230.         break;
  5231.     }
  5232.  
  5233.     vim_free(buffer);
  5234.     close(fd_in);
  5235.     if (close(fd_out) < 0)
  5236.     errmsg = _("E209: Error closing \"%s\"");
  5237.     if (n < 0)
  5238.     {
  5239.     errmsg = _("E210: Error reading \"%s\"");
  5240.     to = from;
  5241.     }
  5242.     if (errmsg != NULL)
  5243.     {
  5244.     EMSG2(errmsg, to);
  5245.     return -1;
  5246.     }
  5247.     mch_remove(from);
  5248.     return 0;
  5249. }
  5250.  
  5251. static int already_warned = FALSE;
  5252.  
  5253. /*
  5254.  * Check if any not hidden buffer has been changed.
  5255.  * Postpone the check if there are characters in the stuff buffer, a global
  5256.  * command is being executed, a mapping is being executed or an autocommand is
  5257.  * busy.
  5258.  * Returns TRUE if some message was written (screen should be redrawn and
  5259.  * cursor positioned).
  5260.  */
  5261.     int
  5262. check_timestamps(focus)
  5263.     int        focus;        /* called for GUI focus event */
  5264. {
  5265.     buf_T    *buf;
  5266.     int        didit = 0;
  5267.     int        n;
  5268.  
  5269.     /* Don't check timestamps while system() or another low-level function may
  5270.      * cause us to lose and gain focus. */
  5271.     if (no_check_timestamps > 0)
  5272.     return FALSE;
  5273.  
  5274.     /* Avoid doing a check twice.  The OK/Reload dialog can cause a focus
  5275.      * event and we would keep on checking if the file is steadily growing.
  5276.      * Do check again after typing something. */
  5277.     if (focus && did_check_timestamps)
  5278.     {
  5279.     need_check_timestamps = TRUE;
  5280.     return FALSE;
  5281.     }
  5282.  
  5283.     if (!stuff_empty() || global_busy || !typebuf_typed()
  5284. #ifdef FEAT_AUTOCMD
  5285.             || autocmd_busy
  5286. #endif
  5287.                     )
  5288.     need_check_timestamps = TRUE;        /* check later */
  5289.     else
  5290.     {
  5291.     ++no_wait_return;
  5292.     did_check_timestamps = TRUE;
  5293.     already_warned = FALSE;
  5294.     for (buf = firstbuf; buf != NULL; )
  5295.     {
  5296.         /* Only check buffers in a window. */
  5297.         if (buf->b_nwindows > 0)
  5298.         {
  5299.         n = buf_check_timestamp(buf, focus);
  5300.         if (didit < n)
  5301.             didit = n;
  5302.         if (n > 0 && !buf_valid(buf))
  5303.         {
  5304.             /* Autocommands have removed the buffer, start at the
  5305.              * first one again. */
  5306.             buf = firstbuf;
  5307.             continue;
  5308.         }
  5309.         }
  5310.         buf = buf->b_next;
  5311.     }
  5312.     --no_wait_return;
  5313.     need_check_timestamps = FALSE;
  5314.     if (need_wait_return && didit == 2)
  5315.     {
  5316.         /* make sure msg isn't overwritten */
  5317.         msg_puts((char_u *)"\n");
  5318.         out_flush();
  5319.     }
  5320.     }
  5321.     return didit;
  5322. }
  5323.  
  5324. /*
  5325.  * Move all the lines from buffer "frombuf" to buffer "tobuf".
  5326.  * Return OK or FAIL.  When FAIL "tobuf" is incomplete and/or "frombuf" is not
  5327.  * empty.
  5328.  */
  5329.     static int
  5330. move_lines(frombuf, tobuf)
  5331.     buf_T    *frombuf;
  5332.     buf_T    *tobuf;
  5333. {
  5334.     buf_T    *tbuf = curbuf;
  5335.     int        retval = OK;
  5336.     linenr_T    lnum;
  5337.     char_u    *p;
  5338.  
  5339.     /* Copy the lines in "frombuf" to "tobuf". */
  5340.     curbuf = tobuf;
  5341.     for (lnum = 1; lnum <= frombuf->b_ml.ml_line_count; ++lnum)
  5342.     {
  5343.     p = vim_strsave(ml_get_buf(frombuf, lnum, FALSE));
  5344.     if (p == NULL || ml_append(lnum - 1, p, 0, FALSE) == FAIL)
  5345.     {
  5346.         vim_free(p);
  5347.         retval = FAIL;
  5348.         break;
  5349.     }
  5350.     vim_free(p);
  5351.     }
  5352.  
  5353.     /* Delete all the lines in "frombuf". */
  5354.     if (retval != FAIL)
  5355.     {
  5356.     curbuf = frombuf;
  5357.     while (!bufempty())
  5358.         if (ml_delete(curbuf->b_ml.ml_line_count, FALSE) == FAIL)
  5359.         {
  5360.         /* Oops!  We could try putting back the saved lines, but that
  5361.          * might fail again... */
  5362.         retval = FAIL;
  5363.         break;
  5364.         }
  5365.     }
  5366.  
  5367.     curbuf = tbuf;
  5368.     return retval;
  5369. }
  5370.  
  5371. /*
  5372.  * Check if buffer "buf" has been changed.
  5373.  * Also check if the file for a new buffer unexpectedly appeared.
  5374.  * return 1 if a changed buffer was found.
  5375.  * return 2 if a message has been displayed.
  5376.  * return 0 otherwise.
  5377.  */
  5378. /*ARGSUSED*/
  5379.     int
  5380. buf_check_timestamp(buf, focus)
  5381.     buf_T    *buf;
  5382.     int        focus;        /* called for GUI focus event */
  5383. {
  5384.     struct stat    st;
  5385.     int        stat_res;
  5386.     int        retval = 0;
  5387.     char_u    *path;
  5388.     char_u    *tbuf;
  5389.     char    *mesg = NULL;
  5390.     int        reload = FALSE;
  5391. #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
  5392.     int        can_reload = FALSE;
  5393. #endif
  5394.     size_t    orig_size = buf->b_orig_size;
  5395.     int        orig_mode = buf->b_orig_mode;
  5396. #ifdef FEAT_GUI
  5397.     int        save_mouse_correct = need_mouse_correct;
  5398. #endif
  5399.  
  5400.     /* If there is no file name, the buffer is not loaded, 'buftype' is
  5401.      * set, or we are in the middle of a save: ignore this buffer. */
  5402.     if (buf->b_ffname == NULL
  5403.         || buf->b_ml.ml_mfp == NULL
  5404. #if defined(FEAT_QUICKFIX)
  5405.         || *buf->b_p_bt != NUL
  5406. #endif
  5407.         || buf->b_saving
  5408.         )
  5409.     return 0;
  5410.  
  5411.     if (       !(buf->b_flags & BF_NOTEDITED)
  5412.         && buf->b_mtime != 0
  5413.         && ((stat_res = mch_stat((char *)buf->b_ffname, &st)) < 0
  5414.         || time_differs((long)st.st_mtime, buf->b_mtime)
  5415. #ifdef HAVE_ST_MODE
  5416.         || (int)st.st_mode != buf->b_orig_mode
  5417. #else
  5418.         || mch_getperm(buf->b_ffname) != buf->b_orig_mode
  5419. #endif
  5420.         ))
  5421.     {
  5422.     retval = 1;
  5423.  
  5424.     /* set b_mtime to stop further warnings */
  5425.     if (stat_res < 0)
  5426.     {
  5427.         buf->b_mtime = 0;
  5428.         buf->b_orig_size = 0;
  5429.         buf->b_orig_mode = 0;
  5430.     }
  5431.     else
  5432.         buf_store_time(buf, &st, buf->b_ffname);
  5433.  
  5434.     /* Don't do anything for a directory.  Might contain the file
  5435.      * explorer. */
  5436.     if (mch_isdir(buf->b_fname))
  5437.         ;
  5438.  
  5439.     /*
  5440.      * If 'autoread' is set, the buffer has no changes and the file still
  5441.      * exists, reload the buffer.  Use the buffer-local option value if it
  5442.      * was set, the global option value otherwise.
  5443.      */
  5444.     else if ((buf->b_p_ar >= 0 ? buf->b_p_ar : p_ar)
  5445.                        && !bufIsChanged(buf) && stat_res >= 0)
  5446.         reload = TRUE;
  5447.     else
  5448.     {
  5449. #ifdef FEAT_AUTOCMD
  5450.         /*
  5451.          * Only give the warning if there are no FileChangedShell
  5452.          * autocommands.
  5453.          */
  5454.         if (apply_autocmds(EVENT_FILECHANGEDSHELL,
  5455.                       buf->b_fname, buf->b_fname, FALSE, buf))
  5456.         {
  5457.         if (!buf_valid(buf))
  5458.         {
  5459.             EMSG(_("E246: FileChangedShell autocommand deleted buffer"));
  5460.         }
  5461.         return 2;
  5462.         }
  5463.         else
  5464. #endif
  5465.         {
  5466.         if (stat_res < 0)
  5467.             mesg = _("E211: Warning: File \"%s\" no longer available");
  5468.         else
  5469.         {
  5470. #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
  5471.             can_reload = TRUE;
  5472. #endif
  5473.             /*
  5474.              * Check if the file contents really changed to avoid
  5475.              * giving a warning when only the timestamp was set (e.g.,
  5476.              * checked out of CVS).  Always warn when the buffer was
  5477.              * changed.
  5478.              */
  5479.             if (bufIsChanged(buf))
  5480.             mesg = _("W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as well");
  5481.             else if (orig_size != buf->b_orig_size
  5482.                 || buf_contents_changed(buf))
  5483.             mesg = _("W11: Warning: File \"%s\" has changed since editing started");
  5484.             else if (orig_mode != buf->b_orig_mode)
  5485.             mesg = _("W16: Warning: Mode of file \"%s\" has changed since editing started");
  5486.         }
  5487.         }
  5488.     }
  5489.  
  5490.     }
  5491.     else if ((buf->b_flags & BF_NEW) && !(buf->b_flags & BF_NEW_W)
  5492.                         && vim_fexists(buf->b_ffname))
  5493.     {
  5494.     retval = 1;
  5495.     mesg = _("W13: Warning: File \"%s\" has been created after editing started");
  5496.     buf->b_flags |= BF_NEW_W;
  5497. #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
  5498.     can_reload = TRUE;
  5499. #endif
  5500.     }
  5501.  
  5502.     if (mesg != NULL)
  5503.     {
  5504.     path = home_replace_save(buf, buf->b_fname);
  5505.     if (path != NULL)
  5506.     {
  5507.         tbuf = alloc((unsigned)(STRLEN(path) + STRLEN(mesg)));
  5508.         sprintf((char *)tbuf, mesg, path);
  5509. #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
  5510.         if (can_reload)
  5511.         {
  5512.         if (do_dialog(VIM_WARNING, (char_u *)_("Warning"), tbuf,
  5513.                 (char_u *)_("&OK\n&Load File"), 1, NULL) == 2)
  5514.             reload = TRUE;
  5515.         }
  5516.         else
  5517. #endif
  5518.         if (State > NORMAL_BUSY || (State & CMDLINE) || already_warned)
  5519.         {
  5520.         EMSG(tbuf);
  5521.         retval = 2;
  5522.         }
  5523.         else
  5524.         {
  5525. # ifdef VIMBUDDY
  5526.         VimBuddyText(tbuf + 9, 2);
  5527. # else
  5528. #  ifdef FEAT_AUTOCMD
  5529.         if (!autocmd_busy)
  5530. #  endif
  5531.         {
  5532.             msg_start();
  5533.             msg_puts_attr(tbuf, hl_attr(HLF_E) + MSG_HIST);
  5534.             msg_clr_eos();
  5535.             (void)msg_end();
  5536.             if (emsg_silent == 0)
  5537.             {
  5538.             out_flush();
  5539. #  ifdef FEAT_GUI
  5540.             if (!focus)
  5541. #  endif
  5542.                 /* give the user some time to think about it */
  5543.                 ui_delay(1000L, TRUE);
  5544.  
  5545.             /* don't redraw and erase the message */
  5546.             redraw_cmdline = FALSE;
  5547.             }
  5548.         }
  5549.         already_warned = TRUE;
  5550. # endif
  5551.         }
  5552.  
  5553.         vim_free(path);
  5554.         vim_free(tbuf);
  5555.     }
  5556.     }
  5557.  
  5558.     if (reload)
  5559.     {
  5560.     exarg_T        ea;
  5561.     pos_T        old_cursor;
  5562.     linenr_T    old_topline;
  5563.     int        old_ro = curbuf->b_p_ro;
  5564.     buf_T        *savebuf;
  5565.     int        saved = OK;
  5566. #ifdef FEAT_AUTOCMD
  5567.     aco_save_T    aco;
  5568.  
  5569.     /* set curwin/curbuf for "buf" and save some things */
  5570.     aucmd_prepbuf(&aco, buf);
  5571. #else
  5572.     buf_T    *save_curbuf = curbuf;
  5573.  
  5574.     curbuf = buf;
  5575.     curwin->w_buffer = buf;
  5576. #endif
  5577.  
  5578.     /* We only want to read the text from the file, not reset the syntax
  5579.      * highlighting, clear marks, diff status, etc.  Force the fileformat
  5580.      * and encoding to be the same. */
  5581.     if (prep_exarg(&ea, buf) == OK)
  5582.     {
  5583.         old_cursor = curwin->w_cursor;
  5584.         old_topline = curwin->w_topline;
  5585.  
  5586.         /*
  5587.          * To behave like when a new file is edited (matters for
  5588.          * BufReadPost autocommands) we first need to delete the current
  5589.          * buffer contents.  But if reading the file fails we should keep
  5590.          * the old contents.  Can't use memory only, the file might be
  5591.          * too big.  Use a hidden buffer to move the buffer contents to.
  5592.          */
  5593.         if (bufempty())
  5594.         savebuf = NULL;
  5595.         else
  5596.         {
  5597.         /* Allocate a buffer without putting it in the buffer list. */
  5598.         savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
  5599.         if (savebuf != NULL)
  5600.         {
  5601.             /* Open the memline. */
  5602.             curbuf = savebuf;
  5603.             curwin->w_buffer = savebuf;
  5604.             saved = ml_open();
  5605.             curbuf = buf;
  5606.             curwin->w_buffer = buf;
  5607.         }
  5608.         if (savebuf == NULL || saved == FAIL
  5609.                       || move_lines(buf, savebuf) == FAIL)
  5610.         {
  5611.             EMSG2(_("E462: Could not prepare for reloading \"%s\""),
  5612.                                 buf->b_fname);
  5613.             saved = FAIL;
  5614.         }
  5615.         }
  5616.  
  5617.         if (saved == OK)
  5618.         {
  5619.         curbuf->b_flags |= BF_CHECK_RO;    /* check for RO again */
  5620. #ifdef FEAT_AUTOCMD
  5621.         keep_filetype = TRUE;        /* don't detect 'filetype' */
  5622. #endif
  5623.         if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0,
  5624.                 (linenr_T)0,
  5625.                 (linenr_T)MAXLNUM, &ea, READ_NEW) == FAIL)
  5626.         {
  5627. #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
  5628.             if (!aborting())
  5629. #endif
  5630.             EMSG2(_("E321: Could not reload \"%s\""), buf->b_fname);
  5631.             if (savebuf != NULL)
  5632.             {
  5633.             /* Put the text back from the save buffer.  First
  5634.              * delete any lines that readfile() added. */
  5635.             while (!bufempty())
  5636.                 if (ml_delete(curbuf->b_ml.ml_line_count, FALSE)
  5637.                                       == FAIL)
  5638.                 break;
  5639.             (void)move_lines(savebuf, buf);
  5640.             }
  5641.         }
  5642.         else
  5643.         {
  5644.             /* Mark the buffer as unmodified and free undo info. */
  5645.             unchanged(buf, TRUE);
  5646.             u_blockfree(buf);
  5647.             u_clearall(buf);
  5648.         }
  5649.         }
  5650.         vim_free(ea.cmd);
  5651.  
  5652.         if (savebuf != NULL)
  5653.         wipe_buffer(savebuf, FALSE);
  5654.  
  5655. #ifdef FEAT_DIFF
  5656.         /* Invalidate diff info if necessary. */
  5657.         diff_invalidate();
  5658. #endif
  5659.  
  5660.         /* Restore the topline and cursor position and check it (lines may
  5661.          * have been removed). */
  5662.         if (old_topline > curbuf->b_ml.ml_line_count)
  5663.         curwin->w_topline = curbuf->b_ml.ml_line_count;
  5664.         else
  5665.         curwin->w_topline = old_topline;
  5666.         curwin->w_cursor = old_cursor;
  5667.         check_cursor();
  5668.         update_topline();
  5669. #ifdef FEAT_AUTOCMD
  5670.         keep_filetype = FALSE;
  5671. #endif
  5672. #ifdef FEAT_FOLDING
  5673.         {
  5674.         win_T *wp;
  5675.  
  5676.         /* Update folds unless they are defined manually. */
  5677.         FOR_ALL_WINDOWS(wp)
  5678.             if (wp->w_buffer == curwin->w_buffer
  5679.                 && !foldmethodIsManual(wp))
  5680.             foldUpdateAll(wp);
  5681.         }
  5682. #endif
  5683.         /* If the mode didn't change and 'readonly' was set, keep the old
  5684.          * value; the user probably used the ":view" command.  But don't
  5685.          * reset it, might have had a read error. */
  5686.         if (orig_mode == curbuf->b_orig_mode)
  5687.         curbuf->b_p_ro |= old_ro;
  5688.     }
  5689.  
  5690. #ifdef FEAT_AUTOCMD
  5691.     /* restore curwin/curbuf and a few other things */
  5692.     aucmd_restbuf(&aco);
  5693.     /* Careful: autocommands may have made "buf" invalid! */
  5694. #else
  5695.     curwin->w_buffer = save_curbuf;
  5696.     curbuf = save_curbuf;
  5697. #endif
  5698.     }
  5699.  
  5700. #ifdef FEAT_GUI
  5701.     /* restore this in case an autocommand has set it; it would break
  5702.      * 'mousefocus' */
  5703.     need_mouse_correct = save_mouse_correct;
  5704. #endif
  5705.  
  5706.     return retval;
  5707. }
  5708.  
  5709. /*ARGSUSED*/
  5710.     void
  5711. buf_store_time(buf, st, fname)
  5712.     buf_T    *buf;
  5713.     struct stat    *st;
  5714.     char_u    *fname;
  5715. {
  5716.     buf->b_mtime = (long)st->st_mtime;
  5717.     buf->b_orig_size = (size_t)st->st_size;
  5718. #ifdef HAVE_ST_MODE
  5719.     buf->b_orig_mode = (int)st->st_mode;
  5720. #else
  5721.     buf->b_orig_mode = mch_getperm(fname);
  5722. #endif
  5723. }
  5724.  
  5725. /*
  5726.  * Adjust the line with missing eol, used for the next write.
  5727.  * Used for do_filter(), when the input lines for the filter are deleted.
  5728.  */
  5729.     void
  5730. write_lnum_adjust(offset)
  5731.     linenr_T    offset;
  5732. {
  5733.     if (write_no_eol_lnum)        /* only if there is a missing eol */
  5734.     write_no_eol_lnum += offset;
  5735. }
  5736.  
  5737. #if defined(TEMPDIRNAMES) || defined(PROTO)
  5738. static long    temp_count = 0;        /* Temp filename counter. */
  5739.  
  5740. /*
  5741.  * Delete the temp directory and all files it contains.
  5742.  */
  5743.     void
  5744. vim_deltempdir()
  5745. {
  5746.     char_u    **files;
  5747.     int        file_count;
  5748.     int        i;
  5749.  
  5750.     if (vim_tempdir != NULL)
  5751.     {
  5752.     sprintf((char *)NameBuff, "%s*", vim_tempdir);
  5753.     if (gen_expand_wildcards(1, &NameBuff, &file_count, &files,
  5754.                           EW_DIR|EW_FILE|EW_SILENT) == OK)
  5755.     {
  5756.         for (i = 0; i < file_count; ++i)
  5757.         mch_remove(files[i]);
  5758.         FreeWild(file_count, files);
  5759.     }
  5760.     gettail(NameBuff)[-1] = NUL;
  5761.     (void)mch_rmdir(NameBuff);
  5762.  
  5763.     vim_free(vim_tempdir);
  5764.     vim_tempdir = NULL;
  5765.     }
  5766. }
  5767. #endif
  5768.  
  5769. /*
  5770.  * vim_tempname(): Return a unique name that can be used for a temp file.
  5771.  *
  5772.  * The temp file is NOT created.
  5773.  *
  5774.  * The returned pointer is to allocated memory.
  5775.  * The returned pointer is NULL if no valid name was found.
  5776.  */
  5777. /*ARGSUSED*/
  5778.     char_u  *
  5779. vim_tempname(extra_char)
  5780.     int        extra_char;        /* character to use in the name instead of '?' */
  5781. {
  5782. #ifdef USE_TMPNAM
  5783.     char_u    itmp[L_tmpnam];    /* use tmpnam() */
  5784. #else
  5785.     char_u    itmp[TEMPNAMELEN];
  5786. #endif
  5787.  
  5788. #ifdef TEMPDIRNAMES
  5789.     static char    *(tempdirs[]) = {TEMPDIRNAMES};
  5790.     int        i;
  5791.     long    nr;
  5792.     long    off;
  5793. # ifndef EEXIST
  5794.     struct stat    st;
  5795. # endif
  5796.  
  5797.     /*
  5798.      * This will create a directory for private use by this instance of Vim.
  5799.      * This is done once, and the same directory is used for all temp files.
  5800.      * This method avoids security problems because of symlink attacks et al.
  5801.      * It's also a bit faster, because we only need to check for an existing
  5802.      * file when creating the directory and not for each temp file.
  5803.      */
  5804.     if (vim_tempdir == NULL)
  5805.     {
  5806.     /*
  5807.      * Try the entries in TEMPDIRNAMES to create the temp directory.
  5808.      */
  5809.     for (i = 0; i < sizeof(tempdirs) / sizeof(char *); ++i)
  5810.     {
  5811.         /* expand $TMP, leave room for "/v1100000/999999999" */
  5812.         expand_env((char_u *)tempdirs[i], itmp, TEMPNAMELEN - 20);
  5813.         if (mch_isdir(itmp))        /* directory exists */
  5814.         {
  5815. # ifdef __EMX__
  5816.         /* If $TMP contains a forward slash (perhaps using bash or
  5817.          * tcsh), don't add a backslash, use a forward slash!
  5818.          * Adding 2 backslashes didn't work. */
  5819.         if (vim_strchr(itmp, '/') != NULL)
  5820.             STRCAT(itmp, "/");
  5821.         else
  5822. # endif
  5823.             add_pathsep(itmp);
  5824.  
  5825.         /* Get an arbitrary number of up to 6 digits.  When it's
  5826.          * unlikely that it already exists it will be faster,
  5827.          * otherwise it doesn't matter.  The use of mkdir() avoids any
  5828.          * security problems because of the predictable number. */
  5829.         nr = (mch_get_pid() + (long)time(NULL)) % 1000000L;
  5830.  
  5831.         /* Try up to 10000 different values until we find a name that
  5832.          * doesn't exist. */
  5833.         for (off = 0; off < 10000L; ++off)
  5834.         {
  5835.             int        r;
  5836. #if defined(UNIX) || defined(VMS)
  5837.             mode_t    umask_save;
  5838. #endif
  5839.  
  5840.             sprintf((char *)itmp + STRLEN(itmp), "v%ld", nr + off);
  5841. # ifndef EEXIST
  5842.             /* If mkdir() does not set errno to EEXIST, check for
  5843.              * existing file here.  There is a race condition then,
  5844.              * although it's fail-safe. */
  5845.             if (mch_stat((char *)itmp, &st) >= 0)
  5846.             continue;
  5847. # endif
  5848. #if defined(UNIX) || defined(VMS)
  5849.             /* Make sure the umask doesn't remove the executable bit.
  5850.              * "repl" has been reported to use "177". */
  5851.             umask_save = umask(077);
  5852. #endif
  5853.             r = vim_mkdir(itmp, 0700);
  5854. #if defined(UNIX) || defined(VMS)
  5855.             (void)umask(umask_save);
  5856. #endif
  5857.             if (r == 0)
  5858.             {
  5859.             char_u    *buf;
  5860.  
  5861.             /* Directory was created, use this name.
  5862.              * Expand to full path; When using the current
  5863.              * directory a ":cd" would confuse us. */
  5864.             buf = alloc((unsigned)MAXPATHL + 1);
  5865.             if (buf != NULL)
  5866.             {
  5867.                 if (vim_FullName(itmp, buf, MAXPATHL, FALSE)
  5868.                                       == FAIL)
  5869.                 STRCPY(buf, itmp);
  5870. # ifdef __EMX__
  5871.                 if (vim_strchr(buf, '/') != NULL)
  5872.                 STRCAT(buf, "/");
  5873.                 else
  5874. # endif
  5875.                 add_pathsep(buf);
  5876.                 vim_tempdir = vim_strsave(buf);
  5877.                 vim_free(buf);
  5878.             }
  5879.             break;
  5880.             }
  5881. # ifdef EEXIST
  5882.             /* If the mkdir() didn't fail because the file/dir exists,
  5883.              * we probably can't create any dir here, try another
  5884.              * place. */
  5885.             if (errno != EEXIST)
  5886. # endif
  5887.             break;
  5888.         }
  5889.         if (vim_tempdir != NULL)
  5890.             break;
  5891.         }
  5892.     }
  5893.     }
  5894.  
  5895.     if (vim_tempdir != NULL)
  5896.     {
  5897.     /* There is no need to check if the file exists, because we own the
  5898.      * directory and nobody else creates a file in it. */
  5899.     sprintf((char *)itmp, "%s%ld", vim_tempdir, temp_count++);
  5900.     return vim_strsave(itmp);
  5901.     }
  5902.  
  5903.     return NULL;
  5904.  
  5905. #else /* TEMPDIRNAMES */
  5906.  
  5907. # ifdef WIN3264
  5908.     char    szTempFile[_MAX_PATH + 1];
  5909.     char    buf4[4];
  5910.     char_u    *retval;
  5911.     char_u    *p;
  5912.  
  5913.     STRCPY(itmp, "");
  5914.     if (GetTempPath(_MAX_PATH, szTempFile) == 0)
  5915.     szTempFile[0] = NUL;    /* GetTempPath() failed, use current dir */
  5916.     strcpy(buf4, "VIM");
  5917.     buf4[2] = extra_char;   /* make it "VIa", "VIb", etc. */
  5918.     if (GetTempFileName(szTempFile, buf4, 0, itmp) == 0)
  5919.     return NULL;
  5920.     /* GetTempFileName() will create the file, we don't want that */
  5921.     (void)DeleteFile(itmp);
  5922.  
  5923.     /* Backslashes in a temp file name cause problems when filtering with
  5924.      * "sh".  NOTE: This also checks 'shellcmdflag' to help those people who
  5925.      * didn't set 'shellslash'. */
  5926.     retval = vim_strsave(itmp);
  5927.     if (*p_shcf == '-' || p_ssl)
  5928.     for (p = retval; *p; ++p)
  5929.         if (*p == '\\')
  5930.         *p = '/';
  5931.     return retval;
  5932.  
  5933. # else /* WIN3264 */
  5934.  
  5935. #  ifdef USE_TMPNAM
  5936.     /* tmpnam() will make its own name */
  5937.     if (*tmpnam((char *)itmp) == NUL)
  5938.     return NULL;
  5939. #  else
  5940.     char_u    *p;
  5941.  
  5942. #   ifdef VMS_TEMPNAM
  5943.     /* mktemp() is not working on VMS.  It seems to be
  5944.      * a do-nothing function. Therefore we use tempnam().
  5945.      */
  5946.     sprintf((char *)itmp, "VIM%c", extra_char);
  5947.     p = (char_u *)tempnam("tmp:", (char *)itmp);
  5948.     if (p != NULL)
  5949.     {
  5950.     /* VMS will use '.LOG' if we don't explicitly specify an extension,
  5951.      * and VIM will then be unable to find the file later */
  5952.     STRCPY(itmp, p);
  5953.     STRCAT(itmp, ".txt");
  5954.     free(p);
  5955.     }
  5956.     else
  5957.     return NULL;
  5958. #   else
  5959.     STRCPY(itmp, TEMPNAME);
  5960.     if ((p = vim_strchr(itmp, '?')) != NULL)
  5961.     *p = extra_char;
  5962.     if (mktemp((char *)itmp) == NULL)
  5963.     return NULL;
  5964. #   endif
  5965. #  endif
  5966.  
  5967.     return vim_strsave(itmp);
  5968. # endif /* WIN3264 */
  5969. #endif /* TEMPDIRNAMES */
  5970. }
  5971.  
  5972. /*
  5973.  * Code for automatic commands.
  5974.  *
  5975.  * Only included when "FEAT_AUTOCMD" has been defined.
  5976.  */
  5977.  
  5978. #if defined(FEAT_AUTOCMD) || defined(PROTO)
  5979.  
  5980. /*
  5981.  * The autocommands are stored in a list for each event.
  5982.  * Autocommands for the same pattern, that are consecutive, are joined
  5983.  * together, to avoid having to match the pattern too often.
  5984.  * The result is an array of Autopat lists, which point to AutoCmd lists:
  5985.  *
  5986.  * first_autopat[0] --> Autopat.next  -->  Autopat.next -->  NULL
  5987.  *            Autopat.cmds       Autopat.cmds
  5988.  *                |             |
  5989.  *                V             V
  5990.  *            AutoCmd.next       AutoCmd.next
  5991.  *                |             |
  5992.  *                V             V
  5993.  *            AutoCmd.next        NULL
  5994.  *                |
  5995.  *                V
  5996.  *               NULL
  5997.  *
  5998.  * first_autopat[1] --> Autopat.next  -->  NULL
  5999.  *            Autopat.cmds
  6000.  *                |
  6001.  *                V
  6002.  *            AutoCmd.next
  6003.  *                |
  6004.  *                V
  6005.  *               NULL
  6006.  *   etc.
  6007.  *
  6008.  *   The order of AutoCmds is important, this is the order in which they were
  6009.  *   defined and will have to be executed.
  6010.  */
  6011. typedef struct AutoCmd
  6012. {
  6013.     char_u        *cmd;        /* The command to be executed (NULL
  6014.                        when command has been removed) */
  6015.     char        nested;        /* If autocommands nest here */
  6016.     char        last;        /* last command in list */
  6017. #ifdef FEAT_EVAL
  6018.     scid_T        scriptID;        /* script ID where defined */
  6019. #endif
  6020.     struct AutoCmd  *next;        /* Next AutoCmd in list */
  6021. } AutoCmd;
  6022.  
  6023. typedef struct AutoPat
  6024. {
  6025.     int            group;        /* group ID */
  6026.     char_u        *pat;        /* pattern as typed (NULL when pattern
  6027.                        has been removed) */
  6028.     int            patlen;        /* strlen() of pat */
  6029.     char_u        *reg_pat;        /* pattern converted to regexp */
  6030.     char        allow_dirs;        /* Pattern may match whole path */
  6031.     char        last;        /* last pattern for apply_autocmds() */
  6032.     AutoCmd        *cmds;        /* list of commands to do */
  6033.     struct AutoPat  *next;        /* next AutoPat in AutoPat list */
  6034. } AutoPat;
  6035.  
  6036. static struct event_name
  6037. {
  6038.     char    *name;    /* event name */
  6039.     EVENT_T    event;    /* event number */
  6040. } event_names[] =
  6041. {
  6042.     {"BufAdd",        EVENT_BUFADD},
  6043.     {"BufCreate",    EVENT_BUFADD},
  6044.     {"BufDelete",    EVENT_BUFDELETE},
  6045.     {"BufEnter",    EVENT_BUFENTER},
  6046.     {"BufFilePost",    EVENT_BUFFILEPOST},
  6047.     {"BufFilePre",    EVENT_BUFFILEPRE},
  6048.     {"BufHidden",    EVENT_BUFHIDDEN},
  6049.     {"BufLeave",    EVENT_BUFLEAVE},
  6050.     {"BufNew",        EVENT_BUFNEW},
  6051.     {"BufNewFile",    EVENT_BUFNEWFILE},
  6052.     {"BufRead",        EVENT_BUFREADPOST},
  6053.     {"BufReadCmd",    EVENT_BUFREADCMD},
  6054.     {"BufReadPost",    EVENT_BUFREADPOST},
  6055.     {"BufReadPre",    EVENT_BUFREADPRE},
  6056.     {"BufUnload",    EVENT_BUFUNLOAD},
  6057.     {"BufWinEnter",    EVENT_BUFWINENTER},
  6058.     {"BufWinLeave",    EVENT_BUFWINLEAVE},
  6059.     {"BufWipeout",    EVENT_BUFWIPEOUT},
  6060.     {"BufWrite",    EVENT_BUFWRITEPRE},
  6061.     {"BufWritePost",    EVENT_BUFWRITEPOST},
  6062.     {"BufWritePre",    EVENT_BUFWRITEPRE},
  6063.     {"BufWriteCmd",    EVENT_BUFWRITECMD},
  6064.     {"CmdwinEnter",    EVENT_CMDWINENTER},
  6065.     {"CmdwinLeave",    EVENT_CMDWINLEAVE},
  6066.     {"EncodingChanged",    EVENT_ENCODINGCHANGED},
  6067.     {"FileEncoding",    EVENT_ENCODINGCHANGED},
  6068.     {"CursorHold",    EVENT_CURSORHOLD},
  6069.     {"FileAppendPost",    EVENT_FILEAPPENDPOST},
  6070.     {"FileAppendPre",    EVENT_FILEAPPENDPRE},
  6071.     {"FileAppendCmd",    EVENT_FILEAPPENDCMD},
  6072.     {"FileChangedShell",EVENT_FILECHANGEDSHELL},
  6073.     {"FileChangedRO",    EVENT_FILECHANGEDRO},
  6074.     {"FileReadPost",    EVENT_FILEREADPOST},
  6075.     {"FileReadPre",    EVENT_FILEREADPRE},
  6076.     {"FileReadCmd",    EVENT_FILEREADCMD},
  6077.     {"FileType",    EVENT_FILETYPE},
  6078.     {"FileWritePost",    EVENT_FILEWRITEPOST},
  6079.     {"FileWritePre",    EVENT_FILEWRITEPRE},
  6080.     {"FileWriteCmd",    EVENT_FILEWRITECMD},
  6081.     {"FilterReadPost",    EVENT_FILTERREADPOST},
  6082.     {"FilterReadPre",    EVENT_FILTERREADPRE},
  6083.     {"FilterWritePost",    EVENT_FILTERWRITEPOST},
  6084.     {"FilterWritePre",    EVENT_FILTERWRITEPRE},
  6085.     {"FocusGained",    EVENT_FOCUSGAINED},
  6086.     {"FocusLost",    EVENT_FOCUSLOST},
  6087.     {"FuncUndefined",    EVENT_FUNCUNDEFINED},
  6088.     {"GUIEnter",    EVENT_GUIENTER},
  6089.     {"RemoteReply",    EVENT_REMOTEREPLY},
  6090.     {"StdinReadPost",    EVENT_STDINREADPOST},
  6091.     {"StdinReadPre",    EVENT_STDINREADPRE},
  6092.     {"Syntax",        EVENT_SYNTAX},
  6093.     {"TermChanged",    EVENT_TERMCHANGED},
  6094.     {"TermResponse",    EVENT_TERMRESPONSE},
  6095.     {"User",        EVENT_USER},
  6096.     {"VimEnter",    EVENT_VIMENTER},
  6097.     {"VimLeave",    EVENT_VIMLEAVE},
  6098.     {"VimLeavePre",    EVENT_VIMLEAVEPRE},
  6099.     {"WinEnter",    EVENT_WINENTER},
  6100.     {"WinLeave",    EVENT_WINLEAVE},
  6101.     {NULL,        (EVENT_T)0}
  6102. };
  6103.  
  6104. static AutoPat *first_autopat[NUM_EVENTS] =
  6105. {
  6106.     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  6107.     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  6108.     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  6109.     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  6110.     NULL, NULL, NULL, NULL, NULL, NULL, NULL
  6111. };
  6112.  
  6113. /*
  6114.  * struct used to keep status while executing autocommands for an event.
  6115.  */
  6116. typedef struct AutoPatCmd
  6117. {
  6118.     AutoPat    *curpat;    /* next AutoPat to examine */
  6119.     AutoCmd    *nextcmd;    /* next AutoCmd to execute */
  6120.     int        group;        /* group being used */
  6121.     char_u    *fname;        /* fname to match with */
  6122.     char_u    *sfname;    /* sfname to match with */
  6123.     char_u    *tail;        /* tail of fname */
  6124.     EVENT_T    event;        /* current event */
  6125. } AutoPatCmd;
  6126.  
  6127. /*
  6128.  * augroups stores a list of autocmd group names.
  6129.  */
  6130. garray_T augroups = {0, 0, sizeof(char_u *), 10, NULL};
  6131. #define AUGROUP_NAME(i) (((char_u **)augroups.ga_data)[i])
  6132.  
  6133. /*
  6134.  * The ID of the current group.  Group 0 is the default one.
  6135.  */
  6136. #define AUGROUP_DEFAULT        -1        /* default autocmd group */
  6137. #define AUGROUP_ERROR        -2        /* errornouse autocmd group */
  6138. #define AUGROUP_ALL        -3        /* all autocmd groups */
  6139. static int current_augroup = AUGROUP_DEFAULT;
  6140.  
  6141. static int au_need_clean = FALSE;   /* need to delete marked patterns */
  6142.  
  6143. static void show_autocmd __ARGS((AutoPat *ap, EVENT_T event));
  6144. static void au_remove_pat __ARGS((AutoPat *ap));
  6145. static void au_remove_cmds __ARGS((AutoPat *ap));
  6146. static void au_cleanup __ARGS((void));
  6147. static int au_new_group __ARGS((char_u *name));
  6148. static void au_del_group __ARGS((char_u *name));
  6149. static int au_find_group __ARGS((char_u *name));
  6150. static EVENT_T event_name2nr __ARGS((char_u *start, char_u **end));
  6151. static char_u *event_nr2name __ARGS((EVENT_T event));
  6152. static char_u *find_end_event __ARGS((char_u *arg));
  6153. static int event_ignored __ARGS((EVENT_T event));
  6154. static int au_get_grouparg __ARGS((char_u **argp));
  6155. static int do_autocmd_event __ARGS((EVENT_T event, char_u *pat, int nested, char_u *cmd, int forceit, int group));
  6156. static char_u *getnextac __ARGS((int c, void *cookie, int indent));
  6157. static int apply_autocmds_group __ARGS((EVENT_T event, char_u *fname, char_u *fname_io, int force, int group, buf_T *buf, exarg_T *eap));
  6158. static void auto_next_pat __ARGS((AutoPatCmd *apc, int stop_at_last));
  6159.  
  6160. static EVENT_T    last_event;
  6161. static int    last_group;
  6162.  
  6163. #ifdef BACKSLASH_IN_FILENAME
  6164. static void forward_slash __ARGS((char_u *));
  6165.  
  6166. /*
  6167.  * Convert all backslashes in fname to forward slashes in-place.
  6168.  */
  6169.     static void
  6170. forward_slash(fname)
  6171.     char_u    *fname;
  6172. {
  6173.     char_u    *p;
  6174.  
  6175.     for (p = fname; *p != NUL; ++p)
  6176. # ifdef  FEAT_MBYTE
  6177.     /* The Big5 encoding can have '\' in the trail byte. */
  6178.     if (enc_dbcs != 0 && (*mb_ptr2len_check)(p) > 1)
  6179.         ++p;
  6180.     else
  6181. # endif
  6182.     if (*p == '\\')
  6183.         *p = '/';
  6184. }
  6185. #endif
  6186.  
  6187. /*
  6188.  * Show the autocommands for one AutoPat.
  6189.  */
  6190.     static void
  6191. show_autocmd(ap, event)
  6192.     AutoPat    *ap;
  6193.     EVENT_T    event;
  6194. {
  6195.     AutoCmd *ac;
  6196.  
  6197.     /* Check for "got_int" (here and at various places below), which is set
  6198.      * when "q" has been hit for the "--more--" prompt */
  6199.     if (got_int)
  6200.     return;
  6201.     if (ap->pat == NULL)        /* pattern has been removed */
  6202.     return;
  6203.  
  6204.     msg_putchar('\n');
  6205.     if (got_int)
  6206.     return;
  6207.     if (event != last_event || ap->group != last_group)
  6208.     {
  6209.     if (ap->group != AUGROUP_DEFAULT)
  6210.     {
  6211.         if (AUGROUP_NAME(ap->group) == NULL)
  6212.         msg_puts_attr((char_u *)_("--Deleted--"), hl_attr(HLF_E));
  6213.         else
  6214.         msg_puts_attr(AUGROUP_NAME(ap->group), hl_attr(HLF_T));
  6215.         msg_puts((char_u *)"  ");
  6216.     }
  6217.     msg_puts_attr(event_nr2name(event), hl_attr(HLF_T));
  6218.     last_event = event;
  6219.     last_group = ap->group;
  6220.     msg_putchar('\n');
  6221.     if (got_int)
  6222.         return;
  6223.     }
  6224.     msg_col = 4;
  6225.     msg_outtrans(ap->pat);
  6226.  
  6227.     for (ac = ap->cmds; ac != NULL; ac = ac->next)
  6228.     {
  6229.     if (ac->cmd != NULL)        /* skip removed commands */
  6230.     {
  6231.         if (msg_col >= 14)
  6232.         msg_putchar('\n');
  6233.         msg_col = 14;
  6234.         if (got_int)
  6235.         return;
  6236.         msg_outtrans(ac->cmd);
  6237.         if (got_int)
  6238.         return;
  6239.         if (ac->next != NULL)
  6240.         {
  6241.         msg_putchar('\n');
  6242.         if (got_int)
  6243.             return;
  6244.         }
  6245.     }
  6246.     }
  6247. }
  6248.  
  6249. /*
  6250.  * Mark an autocommand pattern for deletion.
  6251.  */
  6252.     static void
  6253. au_remove_pat(ap)
  6254.     AutoPat *ap;
  6255. {
  6256.     vim_free(ap->pat);
  6257.     ap->pat = NULL;
  6258.     au_need_clean = TRUE;
  6259. }
  6260.  
  6261. /*
  6262.  * Mark all commands for a pattern for deletion.
  6263.  */
  6264.     static void
  6265. au_remove_cmds(ap)
  6266.     AutoPat *ap;
  6267. {
  6268.     AutoCmd *ac;
  6269.  
  6270.     for (ac = ap->cmds; ac != NULL; ac = ac->next)
  6271.     {
  6272.     vim_free(ac->cmd);
  6273.     ac->cmd = NULL;
  6274.     }
  6275.     au_need_clean = TRUE;
  6276. }
  6277.  
  6278. /*
  6279.  * Cleanup autocommands and patterns that have been deleted.
  6280.  * This is only done when not executing autocommands.
  6281.  */
  6282.     static void
  6283. au_cleanup()
  6284. {
  6285.     AutoPat    *ap, **prev_ap;
  6286.     AutoCmd    *ac, **prev_ac;
  6287.     EVENT_T    event;
  6288.  
  6289.     if (autocmd_busy || !au_need_clean)
  6290.     return;
  6291.  
  6292.     /* loop over all events */
  6293.     for (event = (EVENT_T)0; (int)event < (int)NUM_EVENTS;
  6294.                         event = (EVENT_T)((int)event + 1))
  6295.     {
  6296.     /* loop over all autocommand patterns */
  6297.     prev_ap = &(first_autopat[(int)event]);
  6298.     for (ap = *prev_ap; ap != NULL; ap = *prev_ap)
  6299.     {
  6300.         /* loop over all commands for this pattern */
  6301.         prev_ac = &(ap->cmds);
  6302.         for (ac = *prev_ac; ac != NULL; ac = *prev_ac)
  6303.         {
  6304.         /* remove the command if the pattern is to be deleted or when
  6305.          * the command has been marked for deletion */
  6306.         if (ap->pat == NULL || ac->cmd == NULL)
  6307.         {
  6308.             *prev_ac = ac->next;
  6309.             vim_free(ac->cmd);
  6310.             vim_free(ac);
  6311.         }
  6312.         else
  6313.             prev_ac = &(ac->next);
  6314.         }
  6315.  
  6316.         /* remove the pattern if it has been marked for deletion */
  6317.         if (ap->pat == NULL)
  6318.         {
  6319.         *prev_ap = ap->next;
  6320.         vim_free(ap->reg_pat);
  6321.         vim_free(ap);
  6322.         }
  6323.         else
  6324.         prev_ap = &(ap->next);
  6325.     }
  6326.     }
  6327.  
  6328.     au_need_clean = FALSE;
  6329. }
  6330.  
  6331. /*
  6332.  * Add an autocmd group name.
  6333.  * Return it's ID.  Returns AUGROUP_ERROR (< 0) for error.
  6334.  */
  6335.     static int
  6336. au_new_group(name)
  6337.     char_u    *name;
  6338. {
  6339.     int        i;
  6340.  
  6341.     i = au_find_group(name);
  6342.     if (i == AUGROUP_ERROR)    /* the group doesn't exist yet, add it */
  6343.     {
  6344.     /* First try using a free entry. */
  6345.     for (i = 0; i < augroups.ga_len; ++i)
  6346.         if (AUGROUP_NAME(i) == NULL)
  6347.         break;
  6348.     if (i == augroups.ga_len && ga_grow(&augroups, 1) == FAIL)
  6349.         return AUGROUP_ERROR;
  6350.  
  6351.     AUGROUP_NAME(i) = vim_strsave(name);
  6352.     if (AUGROUP_NAME(i) == NULL)
  6353.         return AUGROUP_ERROR;
  6354.     if (i == augroups.ga_len)
  6355.     {
  6356.         ++augroups.ga_len;
  6357.         --augroups.ga_room;
  6358.     }
  6359.     }
  6360.  
  6361.     return i;
  6362. }
  6363.  
  6364.     static void
  6365. au_del_group(name)
  6366.     char_u    *name;
  6367. {
  6368.     int        i;
  6369.  
  6370.     i = au_find_group(name);
  6371.     if (i == AUGROUP_ERROR)    /* the group doesn't exist */
  6372.     EMSG2(_("E367: No such group: \"%s\""), name);
  6373.     else
  6374.     {
  6375.     vim_free(AUGROUP_NAME(i));
  6376.     AUGROUP_NAME(i) = NULL;
  6377.     }
  6378. }
  6379.  
  6380. /*
  6381.  * Find the ID of an autocmd group name.
  6382.  * Return it's ID.  Returns AUGROUP_ERROR (< 0) for error.
  6383.  */
  6384.     static int
  6385. au_find_group(name)
  6386.     char_u    *name;
  6387. {
  6388.     int        i;
  6389.  
  6390.     for (i = 0; i < augroups.ga_len; ++i)
  6391.     if (AUGROUP_NAME(i) != NULL && STRCMP(AUGROUP_NAME(i), name) == 0)
  6392.         return i;
  6393.     return AUGROUP_ERROR;
  6394. }
  6395.  
  6396. /*
  6397.  * ":augroup {name}".
  6398.  */
  6399.     void
  6400. do_augroup(arg, del_group)
  6401.     char_u    *arg;
  6402.     int        del_group;
  6403. {
  6404.     int        i;
  6405.  
  6406.     if (del_group)
  6407.     {
  6408.     if (*arg == NUL)
  6409.         EMSG(_(e_argreq));
  6410.     else
  6411.         au_del_group(arg);
  6412.     }
  6413.     else if (STRICMP(arg, "end") == 0)   /* ":aug end": back to group 0 */
  6414.     current_augroup = AUGROUP_DEFAULT;
  6415.     else if (*arg)            /* ":aug xxx": switch to group xxx */
  6416.     {
  6417.     i = au_new_group(arg);
  6418.     if (i != AUGROUP_ERROR)
  6419.         current_augroup = i;
  6420.     }
  6421.     else                /* ":aug": list the group names */
  6422.     {
  6423.     msg_start();
  6424.     for (i = 0; i < augroups.ga_len; ++i)
  6425.     {
  6426.         if (AUGROUP_NAME(i) != NULL)
  6427.         {
  6428.         msg_puts(AUGROUP_NAME(i));
  6429.         msg_puts((char_u *)"  ");
  6430.         }
  6431.     }
  6432.     msg_clr_eos();
  6433.     msg_end();
  6434.     }
  6435. }
  6436.  
  6437. /*
  6438.  * Return the event number for event name "start".
  6439.  * Return NUM_EVENTS if the event name was not found.
  6440.  * Return a pointer to the next event name in "end".
  6441.  */
  6442.     static EVENT_T
  6443. event_name2nr(start, end)
  6444.     char_u  *start;
  6445.     char_u  **end;
  6446. {
  6447.     char_u    *p;
  6448.     int        i;
  6449.     int        len;
  6450.  
  6451.     /* the event name ends with end of line, a blank or a comma */
  6452.     for (p = start; *p && !vim_iswhite(*p) && *p != ','; ++p)
  6453.     ;
  6454.     for (i = 0; event_names[i].name != NULL; ++i)
  6455.     {
  6456.     len = (int)STRLEN(event_names[i].name);
  6457.     if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0)
  6458.         break;
  6459.     }
  6460.     if (*p == ',')
  6461.     ++p;
  6462.     *end = p;
  6463.     if (event_names[i].name == NULL)
  6464.     return NUM_EVENTS;
  6465.     return event_names[i].event;
  6466. }
  6467.  
  6468. /*
  6469.  * Return the name for event "event".
  6470.  */
  6471.     static char_u *
  6472. event_nr2name(event)
  6473.     EVENT_T    event;
  6474. {
  6475.     int        i;
  6476.  
  6477.     for (i = 0; event_names[i].name != NULL; ++i)
  6478.     if (event_names[i].event == event)
  6479.         return (char_u *)event_names[i].name;
  6480.     return (char_u *)"Unknown";
  6481. }
  6482.  
  6483. /*
  6484.  * Scan over the events.  "*" stands for all events.
  6485.  */
  6486.     static char_u *
  6487. find_end_event(arg)
  6488.     char_u  *arg;
  6489. {
  6490.     char_u  *pat;
  6491.     char_u  *p;
  6492.  
  6493.     if (*arg == '*')
  6494.     {
  6495.     if (arg[1] && !vim_iswhite(arg[1]))
  6496.     {
  6497.         EMSG2(_("E215: Illegal character after *: %s"), arg);
  6498.         return NULL;
  6499.     }
  6500.     pat = arg + 1;
  6501.     }
  6502.     else
  6503.     {
  6504.     for (pat = arg; *pat && !vim_iswhite(*pat); pat = p)
  6505.     {
  6506.         if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS)
  6507.         {
  6508.         EMSG2(_("E216: No such event: %s"), pat);
  6509.         return NULL;
  6510.         }
  6511.     }
  6512.     }
  6513.     return pat;
  6514. }
  6515.  
  6516. /*
  6517.  * Return TRUE if "event" is included in 'eventignore'.
  6518.  */
  6519.     static int
  6520. event_ignored(event)
  6521.     EVENT_T    event;
  6522. {
  6523.     char_u    *p = p_ei;
  6524.  
  6525.     if (STRICMP(p_ei, "all") == 0)
  6526.     return TRUE;
  6527.  
  6528.     while (*p)
  6529.     if (event_name2nr(p, &p) == event)
  6530.         return TRUE;
  6531.  
  6532.     return FALSE;
  6533. }
  6534.  
  6535. /*
  6536.  * Return OK when the contents of p_ei is valid, FAIL otherwise.
  6537.  */
  6538.     int
  6539. check_ei()
  6540. {
  6541.     char_u    *p = p_ei;
  6542.  
  6543.     if (STRICMP(p_ei, "all") == 0)
  6544.     return OK;
  6545.  
  6546.     while (*p)
  6547.     if (event_name2nr(p, &p) == NUM_EVENTS)
  6548.         return FAIL;
  6549.  
  6550.     return OK;
  6551. }
  6552.  
  6553. /*
  6554.  * do_autocmd() -- implements the :autocmd command.  Can be used in the
  6555.  *  following ways:
  6556.  *
  6557.  * :autocmd <event> <pat> <cmd>        Add <cmd> to the list of commands that
  6558.  *                    will be automatically executed for <event>
  6559.  *                    when editing a file matching <pat>, in
  6560.  *                    the current group.
  6561.  * :autocmd <event> <pat>        Show the auto-commands associated with
  6562.  *                    <event> and <pat>.
  6563.  * :autocmd <event>            Show the auto-commands associated with
  6564.  *                    <event>.
  6565.  * :autocmd                Show all auto-commands.
  6566.  * :autocmd! <event> <pat> <cmd>    Remove all auto-commands associated with
  6567.  *                    <event> and <pat>, and add the command
  6568.  *                    <cmd>, for the current group.
  6569.  * :autocmd! <event> <pat>        Remove all auto-commands associated with
  6570.  *                    <event> and <pat> for the current group.
  6571.  * :autocmd! <event>            Remove all auto-commands associated with
  6572.  *                    <event> for the current group.
  6573.  * :autocmd!                Remove ALL auto-commands for the current
  6574.  *                    group.
  6575.  *
  6576.  *  Multiple events and patterns may be given separated by commas.  Here are
  6577.  *  some examples:
  6578.  * :autocmd bufread,bufenter *.c,*.h    set tw=0 smartindent noic
  6579.  * :autocmd bufleave         *        set tw=79 nosmartindent ic infercase
  6580.  *
  6581.  * :autocmd * *.c        show all autocommands for *.c files.
  6582.  */
  6583.     void
  6584. do_autocmd(arg, forceit)
  6585.     char_u  *arg;
  6586.     int        forceit;
  6587. {
  6588.     char_u    *pat;
  6589.     char_u    *envpat = NULL;
  6590.     char_u    *cmd;
  6591.     EVENT_T    event;
  6592.     int        need_free = FALSE;
  6593.     int        nested = FALSE;
  6594.     int        group;
  6595.  
  6596.     /*
  6597.      * Check for a legal group name.  If not, use AUGROUP_ALL.
  6598.      */
  6599.     group = au_get_grouparg(&arg);
  6600.     if (arg == NULL)        /* out of memory */
  6601.     return;
  6602.  
  6603.     /*
  6604.      * Scan over the events.
  6605.      * If we find an illegal name, return here, don't do anything.
  6606.      */
  6607.     pat = find_end_event(arg);
  6608.     if (pat == NULL)
  6609.     return;
  6610.  
  6611.     /*
  6612.      * Scan over the pattern.  Put a NUL at the end.
  6613.      */
  6614.     pat = skipwhite(pat);
  6615.     cmd = pat;
  6616.     while (*cmd && (!vim_iswhite(*cmd) || cmd[-1] == '\\'))
  6617.     cmd++;
  6618.     if (*cmd)
  6619.     *cmd++ = NUL;
  6620.  
  6621.     /* expand environment variables in the pattern */
  6622.     if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL)
  6623.     {
  6624.     envpat = expand_env_save(pat);
  6625.     if (envpat != NULL)
  6626.         pat = envpat;
  6627.     }
  6628.  
  6629.     /*
  6630.      * Check for "nested" flag.
  6631.      */
  6632.     cmd = skipwhite(cmd);
  6633.     if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && vim_iswhite(cmd[6]))
  6634.     {
  6635.     nested = TRUE;
  6636.     cmd = skipwhite(cmd + 6);
  6637.     }
  6638.  
  6639.     /*
  6640.      * Find the start of the commands.
  6641.      * Expand <sfile> in it.
  6642.      */
  6643.     if (*cmd != NUL)
  6644.     {
  6645.     cmd = expand_sfile(cmd);
  6646.     if (cmd == NULL)        /* some error */
  6647.         return;
  6648.     need_free = TRUE;
  6649.     }
  6650.  
  6651.     /*
  6652.      * Print header when showing autocommands.
  6653.      */
  6654.     if (!forceit && *cmd == NUL)
  6655.     {
  6656.     /* Highlight title */
  6657.     MSG_PUTS_TITLE(_("\n--- Auto-Commands ---"));
  6658.     }
  6659.  
  6660.     /*
  6661.      * Loop over the events.
  6662.      */
  6663.     last_event = (EVENT_T)-1;        /* for listing the event name */
  6664.     last_group = AUGROUP_ERROR;        /* for listing the group name */
  6665.     if (*arg == '*' || *arg == NUL)
  6666.     {
  6667.     for (event = (EVENT_T)0; (int)event < (int)NUM_EVENTS;
  6668.                         event = (EVENT_T)((int)event + 1))
  6669.         if (do_autocmd_event(event, pat,
  6670.                      nested, cmd, forceit, group) == FAIL)
  6671.         break;
  6672.     }
  6673.     else
  6674.     {
  6675.     while (*arg && !vim_iswhite(*arg))
  6676.         if (do_autocmd_event(event_name2nr(arg, &arg), pat,
  6677.                     nested,    cmd, forceit, group) == FAIL)
  6678.         break;
  6679.     }
  6680.  
  6681.     if (need_free)
  6682.     vim_free(cmd);
  6683.     vim_free(envpat);
  6684. }
  6685.  
  6686. /*
  6687.  * Find the group ID in a ":autocmd" or ":doautocmd" argument.
  6688.  * The "argp" argument is advanced to the following argument.
  6689.  *
  6690.  * Returns the group ID, AUGROUP_ERROR for error (out of memory).
  6691.  */
  6692.     static int
  6693. au_get_grouparg(argp)
  6694.     char_u    **argp;
  6695. {
  6696.     char_u    *group_name;
  6697.     char_u    *p;
  6698.     char_u    *arg = *argp;
  6699.     int        group = AUGROUP_ALL;
  6700.  
  6701.     p = skiptowhite(arg);
  6702.     if (p > arg)
  6703.     {
  6704.     group_name = vim_strnsave(arg, (int)(p - arg));
  6705.     if (group_name == NULL)        /* out of memory */
  6706.         return AUGROUP_ERROR;
  6707.     group = au_find_group(group_name);
  6708.     if (group == AUGROUP_ERROR)
  6709.         group = AUGROUP_ALL;    /* no match, use all groups */
  6710.     else
  6711.         *argp = skipwhite(p);    /* match, skip over group name */
  6712.     vim_free(group_name);
  6713.     }
  6714.     return group;
  6715. }
  6716.  
  6717. /*
  6718.  * do_autocmd() for one event.
  6719.  * If *pat == NUL do for all patterns.
  6720.  * If *cmd == NUL show entries.
  6721.  * If forceit == TRUE delete entries.
  6722.  * If group is not AUGROUP_ALL, only use this group.
  6723.  */
  6724.     static int
  6725. do_autocmd_event(event, pat, nested, cmd, forceit, group)
  6726.     EVENT_T    event;
  6727.     char_u    *pat;
  6728.     int        nested;
  6729.     char_u    *cmd;
  6730.     int        forceit;
  6731.     int        group;
  6732. {
  6733.     AutoPat    *ap;
  6734.     AutoPat    **prev_ap;
  6735.     AutoCmd    *ac;
  6736.     AutoCmd    **prev_ac;
  6737.     int        brace_level;
  6738.     char_u    *endpat;
  6739.     int        findgroup;
  6740.     int        allgroups;
  6741.     int        patlen;
  6742.  
  6743.     if (group == AUGROUP_ALL)
  6744.     findgroup = current_augroup;
  6745.     else
  6746.     findgroup = group;
  6747.     allgroups = (group == AUGROUP_ALL && !forceit && *cmd == NUL);
  6748.  
  6749.     /*
  6750.      * Show or delete all patterns for an event.
  6751.      */
  6752.     if (*pat == NUL)
  6753.     {
  6754.     for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
  6755.     {
  6756.         if (forceit)  /* delete the AutoPat, if it's in the current group */
  6757.         {
  6758.         if (ap->group == findgroup)
  6759.             au_remove_pat(ap);
  6760.         }
  6761.         else if (group == AUGROUP_ALL || ap->group == group)
  6762.         show_autocmd(ap, event);
  6763.     }
  6764.     }
  6765.  
  6766.     /*
  6767.      * Loop through all the specified patterns.
  6768.      */
  6769.     for ( ; *pat; pat = (*endpat == ',' ? endpat + 1 : endpat))
  6770.     {
  6771.     /*
  6772.      * Find end of the pattern.
  6773.      * Watch out for a comma in braces, like "*.\{obj,o\}".
  6774.      */
  6775.     brace_level = 0;
  6776.     for (endpat = pat; *endpat && (*endpat != ',' || brace_level
  6777.                          || endpat[-1] == '\\'); ++endpat)
  6778.     {
  6779.         if (*endpat == '{')
  6780.         brace_level++;
  6781.         else if (*endpat == '}')
  6782.         brace_level--;
  6783.     }
  6784.     if (pat == endpat)        /* ignore single comma */
  6785.         continue;
  6786.     patlen = (int)(endpat - pat);
  6787.  
  6788.     /*
  6789.      * Find AutoPat entries with this pattern.
  6790.      */
  6791.     prev_ap = &first_autopat[(int)event];
  6792.     while ((ap = *prev_ap) != NULL)
  6793.     {
  6794.         if (ap->pat != NULL)
  6795.         {
  6796.         /* Accept a pattern when:
  6797.          * - a group was specified and it's that group, or a group was
  6798.          *   not specified and it's the current group, or a group was
  6799.          *   not specified and we are listing
  6800.          * - the length of the pattern matches
  6801.          * - the pattern matches
  6802.          */
  6803.         if ((allgroups || ap->group == findgroup)
  6804.             && ap->patlen == patlen
  6805.             && STRNCMP(pat, ap->pat, patlen) == 0)
  6806.         {
  6807.             /*
  6808.              * Remove existing autocommands.
  6809.              * If adding any new autocmd's for this AutoPat, don't
  6810.              * delete the pattern from the autopat list, append to
  6811.              * this list.
  6812.              */
  6813.             if (forceit)
  6814.             {
  6815.             if (*cmd != NUL && ap->next == NULL)
  6816.             {
  6817.                 au_remove_cmds(ap);
  6818.                 break;
  6819.             }
  6820.             au_remove_pat(ap);
  6821.             }
  6822.  
  6823.             /*
  6824.              * Show autocmd's for this autopat
  6825.              */
  6826.             else if (*cmd == NUL)
  6827.             show_autocmd(ap, event);
  6828.  
  6829.             /*
  6830.              * Add autocmd to this autopat, if it's the last one.
  6831.              */
  6832.             else if (ap->next == NULL)
  6833.             break;
  6834.         }
  6835.         }
  6836.         prev_ap = &ap->next;
  6837.     }
  6838.  
  6839.     /*
  6840.      * Add a new command.
  6841.      */
  6842.     if (*cmd != NUL)
  6843.     {
  6844.         /*
  6845.          * If the pattern we want to add a command to does appear at the
  6846.          * end of the list (or not is not in the list at all), add the
  6847.          * pattern at the end of the list.
  6848.          */
  6849.         if (ap == NULL)
  6850.         {
  6851.         ap = (AutoPat *)alloc((unsigned)sizeof(AutoPat));
  6852.         if (ap == NULL)
  6853.             return FAIL;
  6854.         ap->pat = vim_strnsave(pat, patlen);
  6855.         ap->patlen = patlen;
  6856.         if (ap->pat == NULL)
  6857.         {
  6858.             vim_free(ap);
  6859.             return FAIL;
  6860.         }
  6861.         ap->reg_pat = file_pat_to_reg_pat(pat, endpat,
  6862.                                &ap->allow_dirs, TRUE);
  6863.         if (ap->reg_pat == NULL)
  6864.         {
  6865.             vim_free(ap->pat);
  6866.             vim_free(ap);
  6867.             return FAIL;
  6868.         }
  6869.         ap->cmds = NULL;
  6870.         *prev_ap = ap;
  6871.         ap->next = NULL;
  6872.         if (group == AUGROUP_ALL)
  6873.             ap->group = current_augroup;
  6874.         else
  6875.             ap->group = group;
  6876.         }
  6877.  
  6878.         /*
  6879.          * Add the autocmd at the end of the AutoCmd list.
  6880.          */
  6881.         prev_ac = &(ap->cmds);
  6882.         while ((ac = *prev_ac) != NULL)
  6883.         prev_ac = &ac->next;
  6884.         ac = (AutoCmd *)alloc((unsigned)sizeof(AutoCmd));
  6885.         if (ac == NULL)
  6886.         return FAIL;
  6887.         ac->cmd = vim_strsave(cmd);
  6888. #ifdef FEAT_EVAL
  6889.         ac->scriptID = current_SID;
  6890. #endif
  6891.         if (ac->cmd == NULL)
  6892.         {
  6893.         vim_free(ac);
  6894.         return FAIL;
  6895.         }
  6896.         ac->next = NULL;
  6897.         *prev_ac = ac;
  6898.         ac->nested = nested;
  6899.     }
  6900.     }
  6901.  
  6902.     au_cleanup();    /* may really delete removed patterns/commands now */
  6903.     return OK;
  6904. }
  6905.  
  6906. /*
  6907.  * Implementation of ":doautocmd [group] event [fname]".
  6908.  * Return OK for success, FAIL for failure;
  6909.  */
  6910.     int
  6911. do_doautocmd(arg, do_msg)
  6912.     char_u    *arg;
  6913.     int        do_msg;        /* give message for no matching autocmds? */
  6914. {
  6915.     char_u    *fname;
  6916.     int        nothing_done = TRUE;
  6917.     int        group;
  6918.  
  6919.     /*
  6920.      * Check for a legal group name.  If not, use AUGROUP_ALL.
  6921.      */
  6922.     group = au_get_grouparg(&arg);
  6923.     if (arg == NULL)        /* out of memory */
  6924.     return FAIL;
  6925.  
  6926.     if (*arg == '*')
  6927.     {
  6928.     EMSG(_("E217: Can't execute autocommands for ALL events"));
  6929.     return FAIL;
  6930.     }
  6931.  
  6932.     /*
  6933.      * Scan over the events.
  6934.      * If we find an illegal name, return here, don't do anything.
  6935.      */
  6936.     fname = find_end_event(arg);
  6937.     if (fname == NULL)
  6938.     return FAIL;
  6939.  
  6940.     fname = skipwhite(fname);
  6941.  
  6942.     /*
  6943.      * Loop over the events.
  6944.      */
  6945.     while (*arg && !vim_iswhite(*arg))
  6946.     if (apply_autocmds_group(event_name2nr(arg, &arg),
  6947.                       fname, NULL, TRUE, group, curbuf, NULL))
  6948.         nothing_done = FALSE;
  6949.  
  6950.     if (nothing_done && do_msg)
  6951.     MSG(_("No matching autocommands"));
  6952.  
  6953. #ifdef FEAT_EVAL
  6954.     return aborting() ? FAIL : OK;
  6955. #else
  6956.     return OK;
  6957. #endif
  6958. }
  6959.  
  6960. /*
  6961.  * ":doautoall": execute autocommands for each loaded buffer.
  6962.  */
  6963.     void
  6964. ex_doautoall(eap)
  6965.     exarg_T    *eap;
  6966. {
  6967.     int        retval;
  6968.     aco_save_T    aco;
  6969.     buf_T    *buf;
  6970.  
  6971.     /*
  6972.      * This is a bit tricky: For some commands curwin->w_buffer needs to be
  6973.      * equal to curbuf, but for some buffers there may not be a window.
  6974.      * So we change the buffer for the current window for a moment.  This
  6975.      * gives problems when the autocommands make changes to the list of
  6976.      * buffers or windows...
  6977.      */
  6978.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  6979.     {
  6980.     if (curbuf->b_ml.ml_mfp != NULL)
  6981.     {
  6982.         /* find a window for this buffer and save some values */
  6983.         aucmd_prepbuf(&aco, buf);
  6984.  
  6985.         /* execute the autocommands for this buffer */
  6986.         retval = do_doautocmd(eap->arg, FALSE);
  6987.         do_modelines();
  6988.  
  6989.         /* restore the current window */
  6990.         aucmd_restbuf(&aco);
  6991.  
  6992.         /* stop if there is some error or buffer was deleted */
  6993.         if (retval == FAIL || !buf_valid(buf))
  6994.         break;
  6995.     }
  6996.     }
  6997.  
  6998.     check_cursor();        /* just in case lines got deleted */
  6999. }
  7000.  
  7001. /*
  7002.  * Prepare for executing autocommands for (hidden) buffer "buf".
  7003.  * Search a window for the current buffer.  Save the cursor position and
  7004.  * screen offset.
  7005.  * Set "curbuf" and "curwin" to match "buf".
  7006.  */
  7007.     void
  7008. aucmd_prepbuf(aco, buf)
  7009.     aco_save_T    *aco;        /* structure to save values in */
  7010.     buf_T    *buf;        /* new curbuf */
  7011. {
  7012.     win_T    *win;
  7013.  
  7014.     aco->new_curbuf = buf;
  7015.  
  7016.     /* Find a window that is for the new buffer */
  7017.     if (buf == curbuf)        /* be quick when buf is curbuf */
  7018.     win = curwin;
  7019.     else
  7020. #ifdef FEAT_WINDOWS
  7021.     for (win = firstwin; win != NULL; win = win->w_next)
  7022.         if (win->w_buffer == buf)
  7023.         break;
  7024. #else
  7025.     win = NULL;
  7026. #endif
  7027.  
  7028.     /*
  7029.      * Prefer to use an existing window for the buffer, it has the least side
  7030.      * effects (esp. if "buf" is curbuf).
  7031.      * Otherwise, use curwin for "buf".  It might make some items in the
  7032.      * window invalid.  At least save the cursor and topline.
  7033.      */
  7034.     if (win != NULL)
  7035.     {
  7036.     /* there is a window for "buf", make it the curwin */
  7037.     aco->save_curwin = curwin;
  7038.     curwin = win;
  7039.     aco->save_buf = win->w_buffer;
  7040.     aco->new_curwin = win;
  7041.     }
  7042.     else
  7043.     {
  7044.     /* there is no window for "buf", use curwin */
  7045.     aco->save_curwin = NULL;
  7046.     aco->save_buf = curbuf;
  7047.     --curbuf->b_nwindows;
  7048.     curwin->w_buffer = buf;
  7049.     ++buf->b_nwindows;
  7050.  
  7051.     /* save cursor and topline, set them to safe values */
  7052.     aco->save_cursor = curwin->w_cursor;
  7053.     curwin->w_cursor.lnum = 1;
  7054.     curwin->w_cursor.col = 0;
  7055.     aco->save_topline = curwin->w_topline;
  7056.     curwin->w_topline = 1;
  7057. #ifdef FEAT_DIFF
  7058.     aco->save_topfill = curwin->w_topfill;
  7059.     curwin->w_topfill = 0;
  7060. #endif
  7061.     }
  7062.  
  7063.     curbuf = buf;
  7064. }
  7065.  
  7066. /*
  7067.  * Cleanup after executing autocommands for a (hidden) buffer.
  7068.  * Restore the window as it was (if possible).
  7069.  */
  7070.     void
  7071. aucmd_restbuf(aco)
  7072.     aco_save_T    *aco;        /* structure holding saved values */
  7073. {
  7074.     if (aco->save_curwin != NULL)
  7075.     {
  7076.     /* restore curwin */
  7077. #ifdef FEAT_WINDOWS
  7078.     if (win_valid(aco->save_curwin))
  7079. #endif
  7080.     {
  7081.         /* restore the buffer which was previously edited by curwin, if
  7082.          * it's still the same window and it's valid */
  7083.         if (curwin == aco->new_curwin
  7084.             && buf_valid(aco->save_buf)
  7085.             && aco->save_buf->b_ml.ml_mfp != NULL)
  7086.         {
  7087.         --curbuf->b_nwindows;
  7088.         curbuf = aco->save_buf;
  7089.         curwin->w_buffer = curbuf;
  7090.         ++curbuf->b_nwindows;
  7091.         }
  7092.  
  7093.         curwin = aco->save_curwin;
  7094.         curbuf = curwin->w_buffer;
  7095.     }
  7096.     }
  7097.     else
  7098.     {
  7099.     /* restore buffer for curwin if it still exists and is loaded */
  7100.     if (buf_valid(aco->save_buf) && aco->save_buf->b_ml.ml_mfp != NULL)
  7101.     {
  7102.         --curbuf->b_nwindows;
  7103.         curbuf = aco->save_buf;
  7104.         curwin->w_buffer = curbuf;
  7105.         ++curbuf->b_nwindows;
  7106.         curwin->w_cursor = aco->save_cursor;
  7107.         check_cursor();
  7108.         /* check topline < line_count, in case lines got deleted */
  7109.         if (aco->save_topline <= curbuf->b_ml.ml_line_count)
  7110.         {
  7111.         curwin->w_topline = aco->save_topline;
  7112. #ifdef FEAT_DIFF
  7113.         curwin->w_topfill = aco->save_topfill;
  7114. #endif
  7115.         }
  7116.         else
  7117.         {
  7118.         curwin->w_topline = curbuf->b_ml.ml_line_count;
  7119. #ifdef FEAT_DIFF
  7120.         curwin->w_topfill = 0;
  7121. #endif
  7122.         }
  7123.     }
  7124.     }
  7125. }
  7126.  
  7127. static int    autocmd_nested = FALSE;
  7128.  
  7129. /*
  7130.  * Execute autocommands for "event" and file name "fname".
  7131.  * Return TRUE if some commands were executed.
  7132.  */
  7133.     int
  7134. apply_autocmds(event, fname, fname_io, force, buf)
  7135.     EVENT_T    event;
  7136.     char_u    *fname;        /* NULL or empty means use actual file name */
  7137.     char_u    *fname_io;  /* fname to use for <afile> on cmdline */
  7138.     int        force;        /* when TRUE, ignore autocmd_busy */
  7139.     buf_T    *buf;        /* buffer for <abuf> */
  7140. {
  7141.     return apply_autocmds_group(event, fname, fname_io, force,
  7142.                               AUGROUP_ALL, buf, NULL);
  7143. }
  7144.  
  7145. /*
  7146.  * Like apply_autocmds(), but with extra "eap" argument.  This takes care of
  7147.  * setting v:filearg.
  7148.  */
  7149.     static int
  7150. apply_autocmds_exarg(event, fname, fname_io, force, buf, eap)
  7151.     EVENT_T    event;
  7152.     char_u    *fname;
  7153.     char_u    *fname_io;
  7154.     int        force;
  7155.     buf_T    *buf;
  7156.     exarg_T    *eap;
  7157. {
  7158.     return apply_autocmds_group(event, fname, fname_io, force,
  7159.                                AUGROUP_ALL, buf, eap);
  7160. }
  7161.  
  7162. /*
  7163.  * Like apply_autocmds(), but handles the caller's retval.  If the script
  7164.  * processing is being aborted or if retval is FAIL when inside a try
  7165.  * conditional, no autocommands are executed.  If otherwise the autocommands
  7166.  * cause the script to be aborted, retval is set to FAIL.
  7167.  */
  7168.     int
  7169. apply_autocmds_retval(event, fname, fname_io, force, buf, retval)
  7170.     EVENT_T    event;
  7171.     char_u    *fname;        /* NULL or empty means use actual file name */
  7172.     char_u    *fname_io;  /* fname to use for <afile> on cmdline */
  7173.     int        force;        /* when TRUE, ignore autocmd_busy */
  7174.     buf_T    *buf;        /* buffer for <abuf> */
  7175.     int        *retval;    /* pointer to caller's retval */
  7176. {
  7177.     int        did_cmd;
  7178.  
  7179.     if (should_abort(*retval))
  7180.     return FALSE;
  7181.  
  7182.     did_cmd = apply_autocmds_group(event, fname, fname_io, force,
  7183.                               AUGROUP_ALL, buf, NULL);
  7184.     if (did_cmd && aborting())
  7185.     *retval = FAIL;
  7186.     return did_cmd;
  7187. }
  7188.  
  7189. #if defined(FEAT_AUTOCMD) || defined(PROTO)
  7190.     int
  7191. has_cursorhold()
  7192. {
  7193.     return (first_autopat[(int)EVENT_CURSORHOLD] != NULL);
  7194. }
  7195. #endif
  7196.  
  7197.     static int
  7198. apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
  7199.     EVENT_T    event;
  7200.     char_u    *fname;        /* NULL or empty means use actual file name */
  7201.     char_u    *fname_io;  /* fname to use for <afile> on cmdline, NULL means
  7202.                    use fname */
  7203.     int        force;        /* when TRUE, ignore autocmd_busy */
  7204.     int        group;        /* group ID, or AUGROUP_ALL */
  7205.     buf_T    *buf;        /* buffer for <abuf> */
  7206.     exarg_T    *eap;        /* command arguments */
  7207. {
  7208.     char_u    *sfname = NULL;    /* short file name */
  7209.     char_u    *tail;
  7210.     int        save_changed;
  7211.     buf_T    *old_curbuf;
  7212.     int        retval = FALSE;
  7213.     char_u    *save_sourcing_name;
  7214.     linenr_T    save_sourcing_lnum;
  7215.     char_u    *save_autocmd_fname;
  7216.     int        save_autocmd_bufnr;
  7217.     char_u    *save_autocmd_match;
  7218.     int        save_autocmd_busy;
  7219.     int        save_autocmd_nested;
  7220.     static int    nesting = 0;
  7221.     AutoPatCmd    patcmd;
  7222.     AutoPat    *ap;
  7223. #ifdef FEAT_EVAL
  7224.     scid_T    save_current_SID;
  7225.     void    *save_funccalp;
  7226.     char_u    *save_cmdarg;
  7227. #endif
  7228.     static int    filechangeshell_busy = FALSE;
  7229.  
  7230.     /*
  7231.      * Quickly return if there are no autocommands for this event or
  7232.      * autocommands are blocked.
  7233.      */
  7234.     if (first_autopat[(int)event] == NULL || autocmd_block > 0)
  7235.     return retval;
  7236.  
  7237.     /*
  7238.      * When autocommands are busy, new autocommands are only executed when
  7239.      * explicitly enabled with the "nested" flag.
  7240.      */
  7241.     if (autocmd_busy && !(force || autocmd_nested))
  7242.     return retval;
  7243.  
  7244. #ifdef FEAT_EVAL
  7245.     /*
  7246.      * Quickly return when immdediately aborting on error, or when an interrupt
  7247.      * occurred or an exception was thrown but not caught.
  7248.      */
  7249.     if (aborting())
  7250.     return retval;
  7251. #endif
  7252.  
  7253.     /*
  7254.      * FileChangedShell never nests, because it can create an endless loop.
  7255.      */
  7256.     if (filechangeshell_busy && event == EVENT_FILECHANGEDSHELL)
  7257.     return retval;
  7258.  
  7259.     /*
  7260.      * Ignore events in 'eventignore'.
  7261.      */
  7262.     if (event_ignored(event))
  7263.     return retval;
  7264.  
  7265.     /*
  7266.      * Allow nesting of autocommands, but restrict the depth, because it's
  7267.      * possible to create an endless loop.
  7268.      */
  7269.     if (nesting == 10)
  7270.     {
  7271.     EMSG(_("E218: autocommand nesting too deep"));
  7272.     return retval;
  7273.     }
  7274.  
  7275.     /*
  7276.      * Check if these autocommands are disabled.  Used when doing ":all" or
  7277.      * ":ball".
  7278.      */
  7279.     if (       (autocmd_no_enter
  7280.         && (event == EVENT_WINENTER || event == EVENT_BUFENTER))
  7281.         || (autocmd_no_leave
  7282.         && (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE)))
  7283.     return retval;
  7284.  
  7285.     /*
  7286.      * Save the autocmd_* variables and info about the current buffer.
  7287.      */
  7288.     save_autocmd_fname = autocmd_fname;
  7289.     save_autocmd_bufnr = autocmd_bufnr;
  7290.     save_autocmd_match = autocmd_match;
  7291.     save_autocmd_busy = autocmd_busy;
  7292.     save_autocmd_nested = autocmd_nested;
  7293.     save_changed = curbuf->b_changed;
  7294.     old_curbuf = curbuf;
  7295.  
  7296.     /*
  7297.      * Set the file name to be used for <afile>.
  7298.      */
  7299.     if (fname_io == NULL)
  7300.     {
  7301.     if (fname != NULL && *fname != NUL)
  7302.         autocmd_fname = fname;
  7303.     else if (buf != NULL)
  7304.         autocmd_fname = buf->b_fname;
  7305.     else
  7306.         autocmd_fname = NULL;
  7307.     }
  7308.     else
  7309.     autocmd_fname = fname_io;
  7310.  
  7311.     /*
  7312.      * Set the buffer number to be used for <abuf>.
  7313.      */
  7314.     if (buf == NULL)
  7315.     autocmd_bufnr = 0;
  7316.     else
  7317.     autocmd_bufnr = buf->b_fnum;
  7318.  
  7319.     /*
  7320.      * When the file name is NULL or empty, use the file name of buffer "buf".
  7321.      * Always use the full path of the file name to match with, in case
  7322.      * "allow_dirs" is set.
  7323.      */
  7324.     if (fname == NULL || *fname == NUL)
  7325.     {
  7326.     if (buf == NULL)
  7327.         fname = NULL;
  7328.     else
  7329.     {
  7330. #ifdef FEAT_SYN_HL
  7331.         if (event == EVENT_SYNTAX)
  7332.         fname = buf->b_p_syn;
  7333.         else
  7334. #endif
  7335.         if (event == EVENT_FILETYPE)
  7336.             fname = buf->b_p_ft;
  7337.         else
  7338.         {
  7339.             if (buf->b_sfname != NULL)
  7340.             sfname = vim_strsave(buf->b_sfname);
  7341.             fname = buf->b_ffname;
  7342.         }
  7343.     }
  7344.     if (fname == NULL)
  7345.         fname = (char_u *)"";
  7346.     fname = vim_strsave(fname);    /* make a copy, so we can change it */
  7347.     }
  7348.     else
  7349.     {
  7350.     sfname = vim_strsave(fname);
  7351.     /* Don't try expanding FileType, Syntax or WindowID. */
  7352.     if (event == EVENT_FILETYPE || event == EVENT_SYNTAX
  7353.         || event == EVENT_REMOTEREPLY)
  7354.         fname = vim_strsave(fname);
  7355.     else
  7356.         fname = FullName_save(fname, FALSE);
  7357.     }
  7358.     if (fname == NULL)        /* out of memory */
  7359.     {
  7360.     vim_free(sfname);
  7361.     return FALSE;
  7362.     }
  7363.  
  7364. #ifdef BACKSLASH_IN_FILENAME
  7365.     /*
  7366.      * Replace all backslashes with forward slashes.  This makes the
  7367.      * autocommand patterns portable between Unix and MS-DOS.
  7368.      */
  7369.     if (sfname != NULL)
  7370.     forward_slash(sfname);
  7371.     forward_slash(fname);
  7372. #endif
  7373.  
  7374. #ifdef VMS
  7375.     /* remove version for correct match */
  7376.     if (sfname != NULL)
  7377.     vms_remove_version(sfname);
  7378.     vms_remove_version(fname);
  7379. #endif
  7380.  
  7381.     /*
  7382.      * Set the name to be used for <amatch>.
  7383.      */
  7384.     autocmd_match = fname;
  7385.  
  7386.  
  7387.     /* Don't redraw while doing auto commands. */
  7388.     ++RedrawingDisabled;
  7389.     save_sourcing_name = sourcing_name;
  7390.     sourcing_name = NULL;    /* don't free this one */
  7391.     save_sourcing_lnum = sourcing_lnum;
  7392.     sourcing_lnum = 0;        /* no line number here */
  7393.  
  7394. #ifdef FEAT_EVAL
  7395.     save_current_SID = current_SID;
  7396.  
  7397.     /* Don't use local function variables, if called from a function */
  7398.     save_funccalp = save_funccal();
  7399. #endif
  7400.  
  7401.     /*
  7402.      * When starting to execute autocommands, save the search patterns.
  7403.      */
  7404.     if (!autocmd_busy)
  7405.     {
  7406.     save_search_patterns();
  7407.     saveRedobuff();
  7408.     did_filetype = keep_filetype;
  7409.     }
  7410.  
  7411.     /*
  7412.      * Note that we are applying autocmds.  Some commands need to know.
  7413.      */
  7414.     autocmd_busy = TRUE;
  7415.     filechangeshell_busy = (event == EVENT_FILECHANGEDSHELL);
  7416.     ++nesting;
  7417.  
  7418.     /* Remember that FileType was triggered.  Used for did_filetype(). */
  7419.     if (event == EVENT_FILETYPE)
  7420.     did_filetype = TRUE;
  7421.  
  7422.     tail = gettail(fname);
  7423.  
  7424.     /* Find first autocommand that matches */
  7425.     patcmd.curpat = first_autopat[(int)event];
  7426.     patcmd.nextcmd = NULL;
  7427.     patcmd.group = group;
  7428.     patcmd.fname = fname;
  7429.     patcmd.sfname = sfname;
  7430.     patcmd.tail = tail;
  7431.     patcmd.event = event;
  7432.     auto_next_pat(&patcmd, FALSE);
  7433.  
  7434.     /* found one, start executing the autocommands */
  7435.     if (patcmd.curpat != NULL)
  7436.     {
  7437. #ifdef FEAT_EVAL
  7438.     /* set v:cmdarg (only when there is a matching pattern) */
  7439.     if (eap != NULL)
  7440.         save_cmdarg = set_cmdarg(eap, NULL);
  7441.     else
  7442.         save_cmdarg = NULL;    /* avoid gcc warning */
  7443. #endif
  7444.     retval = TRUE;
  7445.     /* mark the last pattern, to avoid an endless loop when more patterns
  7446.      * are added when executing autocommands */
  7447.     for (ap = patcmd.curpat; ap->next != NULL; ap = ap->next)
  7448.         ap->last = FALSE;
  7449.     ap->last = TRUE;
  7450.     check_lnums(TRUE);    /* make sure cursor and topline are valid */
  7451.     do_cmdline(NULL, getnextac, (void *)&patcmd,
  7452.                      DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
  7453. #ifdef FEAT_EVAL
  7454.     if (eap != NULL)
  7455.         (void)set_cmdarg(NULL, save_cmdarg);
  7456. #endif
  7457.     }
  7458.  
  7459.     --RedrawingDisabled;
  7460.     autocmd_busy = save_autocmd_busy;
  7461.     filechangeshell_busy = FALSE;
  7462.     autocmd_nested = save_autocmd_nested;
  7463.     vim_free(sourcing_name);
  7464.     sourcing_name = save_sourcing_name;
  7465.     sourcing_lnum = save_sourcing_lnum;
  7466.     autocmd_fname = save_autocmd_fname;
  7467.     autocmd_bufnr = save_autocmd_bufnr;
  7468.     autocmd_match = save_autocmd_match;
  7469. #ifdef FEAT_EVAL
  7470.     current_SID = save_current_SID;
  7471.     restore_funccal(save_funccalp);
  7472. #endif
  7473.     vim_free(fname);
  7474.     vim_free(sfname);
  7475.     --nesting;
  7476.  
  7477.     /*
  7478.      * When stopping to execute autocommands, restore the search patterns and
  7479.      * the redo buffer.
  7480.      */
  7481.     if (!autocmd_busy)
  7482.     {
  7483.     restore_search_patterns();
  7484.     restoreRedobuff();
  7485.     did_filetype = FALSE;
  7486.     }
  7487.  
  7488.     /*
  7489.      * Some events don't set or reset the Changed flag.
  7490.      * Check if still in the same buffer!
  7491.      */
  7492.     if (curbuf == old_curbuf
  7493.         && (event == EVENT_BUFREADPOST
  7494.         || event == EVENT_BUFWRITEPOST
  7495.         || event == EVENT_FILEAPPENDPOST
  7496.         || event == EVENT_VIMLEAVE
  7497.         || event == EVENT_VIMLEAVEPRE))
  7498.     {
  7499. #ifdef FEAT_TITLE
  7500.     if (curbuf->b_changed != save_changed)
  7501.         need_maketitle = TRUE;
  7502. #endif
  7503.     curbuf->b_changed = save_changed;
  7504.     }
  7505.  
  7506.     au_cleanup();    /* may really delete removed patterns/commands now */
  7507.     return retval;
  7508. }
  7509.  
  7510. /*
  7511.  * Find next autocommand pattern that matches.
  7512.  */
  7513.     static void
  7514. auto_next_pat(apc, stop_at_last)
  7515.     AutoPatCmd    *apc;
  7516.     int        stop_at_last;        /* stop when 'last' flag is set */
  7517. {
  7518.     AutoPat    *ap;
  7519.     AutoCmd    *cp;
  7520.     char_u    *name;
  7521.     char    *s;
  7522.  
  7523.     vim_free(sourcing_name);
  7524.     sourcing_name = NULL;
  7525.  
  7526.     for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next)
  7527.     {
  7528.     apc->curpat = NULL;
  7529.  
  7530.     /* only use a pattern when it has not been removed, has commands and
  7531.      * the group matches */
  7532.     if (ap->pat != NULL && ap->cmds != NULL
  7533.         && (apc->group == AUGROUP_ALL || apc->group == ap->group))
  7534.     {
  7535.         if (match_file_pat(ap->reg_pat, apc->fname, apc->sfname, apc->tail,
  7536.                                   ap->allow_dirs))
  7537.         {
  7538.         name = event_nr2name(apc->event);
  7539.         s = _("%s Auto commands for \"%s\"");
  7540.         sourcing_name = alloc((unsigned)(STRLEN(s)
  7541.                         + STRLEN(name) + ap->patlen + 1));
  7542.         if (sourcing_name != NULL)
  7543.         {
  7544.             sprintf((char *)sourcing_name, s,
  7545.                            (char *)name, (char *)ap->pat);
  7546.             if (p_verbose >= 8)
  7547.             msg_str((char_u *)_("Executing %s"), sourcing_name);
  7548.         }
  7549.  
  7550.         apc->curpat = ap;
  7551.         apc->nextcmd = ap->cmds;
  7552.         /* mark last command */
  7553.         for (cp = ap->cmds; cp->next != NULL; cp = cp->next)
  7554.             cp->last = FALSE;
  7555.         cp->last = TRUE;
  7556.         }
  7557.         line_breakcheck();
  7558.         if (apc->curpat != NULL)        /* found a match */
  7559.         break;
  7560.     }
  7561.     if (stop_at_last && ap->last)
  7562.         break;
  7563.     }
  7564. }
  7565.  
  7566. /*
  7567.  * Get next autocommand command.
  7568.  * Called by do_cmdline() to get the next line for ":if".
  7569.  * Returns allocated string, or NULL for end of autocommands.
  7570.  */
  7571. /* ARGSUSED */
  7572.     static char_u *
  7573. getnextac(c, cookie, indent)
  7574.     int        c;            /* not used */
  7575.     void    *cookie;
  7576.     int        indent;        /* not used */
  7577. {
  7578.     AutoPatCmd        *acp = (AutoPatCmd *)cookie;
  7579.     char_u        *retval;
  7580.     AutoCmd        *ac;
  7581.  
  7582.     /* Can be called again after returning the last line. */
  7583.     if (acp->curpat == NULL)
  7584.     return NULL;
  7585.  
  7586.     /* repeat until we find an autocommand to execute */
  7587.     for (;;)
  7588.     {
  7589.     /* skip removed commands */
  7590.     while (acp->nextcmd != NULL && acp->nextcmd->cmd == NULL)
  7591.         if (acp->nextcmd->last)
  7592.         acp->nextcmd = NULL;
  7593.         else
  7594.         acp->nextcmd = acp->nextcmd->next;
  7595.  
  7596.     if (acp->nextcmd != NULL)
  7597.         break;
  7598.  
  7599.     /* at end of commands, find next pattern that matches */
  7600.     if (acp->curpat->last)
  7601.         acp->curpat = NULL;
  7602.     else
  7603.         acp->curpat = acp->curpat->next;
  7604.     if (acp->curpat != NULL)
  7605.         auto_next_pat(acp, TRUE);
  7606.     if (acp->curpat == NULL)
  7607.         return NULL;
  7608.     }
  7609.  
  7610.     ac = acp->nextcmd;
  7611.  
  7612.     if (p_verbose >= 9)
  7613.     {
  7614.     msg_scroll = TRUE;        /* always scroll up, don't overwrite */
  7615.     msg_str((char_u *)_("autocommand %s"), ac->cmd);
  7616.     msg_puts((char_u *)"\n");   /* don't overwrite this either */
  7617.     cmdline_row = msg_row;
  7618.     }
  7619.     retval = vim_strsave(ac->cmd);
  7620.     autocmd_nested = ac->nested;
  7621. #ifdef FEAT_EVAL
  7622.     current_SID = ac->scriptID;
  7623. #endif
  7624.     if (ac->last)
  7625.     acp->nextcmd = NULL;
  7626.     else
  7627.     acp->nextcmd = ac->next;
  7628.     return retval;
  7629. }
  7630.  
  7631. /*
  7632.  * Return TRUE if there is a matching autocommand for "fname".
  7633.  */
  7634.     int
  7635. has_autocmd(event, sfname)
  7636.     EVENT_T    event;
  7637.     char_u    *sfname;
  7638. {
  7639.     AutoPat    *ap;
  7640.     char_u    *fname;
  7641.     char_u    *tail = gettail(sfname);
  7642.     int        retval = FALSE;
  7643.  
  7644.     fname = FullName_save(sfname, FALSE);
  7645.     if (fname == NULL)
  7646.     return FALSE;
  7647.  
  7648. #ifdef BACKSLASH_IN_FILENAME
  7649.     /*
  7650.      * Replace all backslashes with forward slashes.  This makes the
  7651.      * autocommand patterns portable between Unix and MS-DOS.
  7652.      */
  7653.     sfname = vim_strsave(sfname);
  7654.     if (sfname != NULL)
  7655.     forward_slash(sfname);
  7656.     forward_slash(fname);
  7657. #endif
  7658.  
  7659.     for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
  7660.     if (ap->pat != NULL && ap->cmds != NULL
  7661.         && match_file_pat(ap->reg_pat, fname, sfname, tail,
  7662.                                   ap->allow_dirs))
  7663.     {
  7664.         retval = TRUE;
  7665.         break;
  7666.     }
  7667.  
  7668.     vim_free(fname);
  7669. #ifdef BACKSLASH_IN_FILENAME
  7670.     vim_free(sfname);
  7671. #endif
  7672.  
  7673.     return retval;
  7674. }
  7675.  
  7676. #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
  7677. /*
  7678.  * Function given to ExpandGeneric() to obtain the list of autocommand group
  7679.  * names.
  7680.  */
  7681. /*ARGSUSED*/
  7682.     char_u *
  7683. get_augroup_name(xp, idx)
  7684.     expand_T    *xp;
  7685.     int        idx;
  7686. {
  7687.     if (idx == augroups.ga_len)        /* add "END" add the end */
  7688.     return (char_u *)"END";
  7689.     if (idx >= augroups.ga_len)        /* end of list */
  7690.     return NULL;
  7691.     if (AUGROUP_NAME(idx) == NULL)    /* skip deleted entries */
  7692.     return (char_u *)"";
  7693.     return AUGROUP_NAME(idx);        /* return a name */
  7694. }
  7695.  
  7696. static int include_groups = FALSE;
  7697.  
  7698.     char_u  *
  7699. set_context_in_autocmd(xp, arg, doautocmd)
  7700.     expand_T    *xp;
  7701.     char_u    *arg;
  7702.     int        doautocmd;    /* TRUE for :doautocmd, FALSE for :autocmd */
  7703. {
  7704.     char_u    *p;
  7705.     int        group;
  7706.  
  7707.     /* check for a group name, skip it if present */
  7708.     include_groups = FALSE;
  7709.     p = arg;
  7710.     group = au_get_grouparg(&arg);
  7711.     if (group == AUGROUP_ERROR)
  7712.     return NULL;
  7713.     /* If there only is a group name that's what we expand. */
  7714.     if (*arg == NUL && group != AUGROUP_ALL && !vim_iswhite(arg[-1]))
  7715.     {
  7716.     arg = p;
  7717.     group = AUGROUP_ALL;
  7718.     }
  7719.  
  7720.     /* skip over event name */
  7721.     for (p = arg; *p != NUL && !vim_iswhite(*p); ++p)
  7722.     if (*p == ',')
  7723.         arg = p + 1;
  7724.     if (*p == NUL)
  7725.     {
  7726.     if (group == AUGROUP_ALL)
  7727.         include_groups = TRUE;
  7728.     xp->xp_context = EXPAND_EVENTS;        /* expand event name */
  7729.     xp->xp_pattern = arg;
  7730.     return NULL;
  7731.     }
  7732.  
  7733.     /* skip over pattern */
  7734.     arg = skipwhite(p);
  7735.     while (*arg && (!vim_iswhite(*arg) || arg[-1] == '\\'))
  7736.     arg++;
  7737.     if (*arg)
  7738.     return arg;                /* expand (next) command */
  7739.  
  7740.     if (doautocmd)
  7741.     xp->xp_context = EXPAND_FILES;        /* expand file names */
  7742.     else
  7743.     xp->xp_context = EXPAND_NOTHING;    /* pattern is not expanded */
  7744.     return NULL;
  7745. }
  7746.  
  7747. /*
  7748.  * Function given to ExpandGeneric() to obtain the list of event names.
  7749.  */
  7750. /*ARGSUSED*/
  7751.     char_u *
  7752. get_event_name(xp, idx)
  7753.     expand_T    *xp;
  7754.     int        idx;
  7755. {
  7756.     if (idx < augroups.ga_len)        /* First list group names, if wanted */
  7757.     {
  7758.     if (!include_groups || AUGROUP_NAME(idx) == NULL)
  7759.         return (char_u *)"";    /* skip deleted entries */
  7760.     return AUGROUP_NAME(idx);    /* return a name */
  7761.     }
  7762.     return (char_u *)event_names[idx - augroups.ga_len].name;
  7763. }
  7764.  
  7765. #endif    /* FEAT_CMDL_COMPL */
  7766.  
  7767. /*
  7768.  * Return TRUE if an autocommand is defined for "event" and "pattern".
  7769.  * "pattern" can be NULL to accept any pattern.
  7770.  */
  7771.     int
  7772. au_exists(name, name_end, pattern)
  7773.     char_u    *name;
  7774.     char_u    *name_end;
  7775.     char_u    *pattern;
  7776. {
  7777.     char_u    *event_name;
  7778.     char_u    *p;
  7779.     EVENT_T    event;
  7780.     AutoPat    *ap;
  7781.  
  7782.     /* find the index (enum) for the event name */
  7783.     event_name = vim_strnsave(name, (int)(name_end - name));
  7784.     if (event_name == NULL)
  7785.     return FALSE;
  7786.     event = event_name2nr(event_name, &p);
  7787.     vim_free(event_name);
  7788.  
  7789.     /* return FALSE if the event name is not recognized */
  7790.     if (event == NUM_EVENTS)        /* unknown event name */
  7791.     return FALSE;
  7792.  
  7793.     /* Find the first autocommand for this event.
  7794.      * If there isn't any, return FALSE;
  7795.      * If there is one and no pattern given, return TRUE; */
  7796.     ap = first_autopat[(int)event];
  7797.     if (ap == NULL)
  7798.     return FALSE;
  7799.     if (pattern == NULL)
  7800.     return TRUE;
  7801.  
  7802.     /* Check if there is an autocommand with the given pattern. */
  7803.     for ( ; ap != NULL; ap = ap->next)
  7804.     /* only use a pattern when it has not been removed and has commands */
  7805.     if (ap->pat != NULL && ap->cmds != NULL
  7806.                        && fnamecmp(ap->pat, pattern) == 0)
  7807.         return TRUE;
  7808.  
  7809.     return FALSE;
  7810. }
  7811. #endif    /* FEAT_AUTOCMD */
  7812.  
  7813. #if defined(FEAT_AUTOCMD) || defined(FEAT_WILDIGN) || defined(PROTO)
  7814. /*
  7815.  * Try matching a filename with a pattern.
  7816.  * Used for autocommands and 'wildignore'.
  7817.  * Returns TRUE if there is a match, FALSE otherwise.
  7818.  */
  7819.     int
  7820. match_file_pat(pattern, fname, sfname, tail, allow_dirs)
  7821.     char_u    *pattern;        /* pattern to match with */
  7822.     char_u    *fname;            /* full path of file name */
  7823.     char_u    *sfname;        /* short file name or NULL */
  7824.     char_u    *tail;            /* tail of path */
  7825.     int        allow_dirs;        /* allow matching with dir */
  7826. {
  7827.     regmatch_T    regmatch;
  7828.     int        result = FALSE;
  7829. #ifdef FEAT_OSFILETYPE
  7830.     int        no_pattern = FALSE; /* TRUE if check is filetype only */
  7831.     char_u    *type_start;
  7832.     char_u    c;
  7833.     int        match = FALSE;
  7834. #endif
  7835.  
  7836. #ifdef CASE_INSENSITIVE_FILENAME
  7837.     regmatch.rm_ic = TRUE;        /* Always ignore case */
  7838. #else
  7839.     regmatch.rm_ic = FALSE;        /* Don't ever ignore case */
  7840. #endif
  7841. #ifdef FEAT_OSFILETYPE
  7842.     if (*pattern == '<')
  7843.     {
  7844.     /* There is a filetype condition specified with this pattern.
  7845.      * Check the filetype matches first. If not, don't bother with the
  7846.      * pattern (set regprog to NULL).
  7847.      * Always use magic for the regexp.
  7848.      */
  7849.  
  7850.     for (type_start = pattern + 1; (c = *pattern); pattern++)
  7851.     {
  7852.         if ((c == ';' || c == '>') && match == FALSE)
  7853.         {
  7854.         *pattern = NUL;        /* Terminate the string */
  7855.         match = mch_check_filetype(fname, type_start);
  7856.         *pattern = c;        /* Restore the terminator */
  7857.         type_start = pattern + 1;
  7858.         }
  7859.         if (c == '>')
  7860.         break;
  7861.     }
  7862.  
  7863.     /* (c should never be NUL, but check anyway) */
  7864.     if (match == FALSE || c == NUL)
  7865.         regmatch.regprog = NULL;    /* Doesn't match - don't check pat. */
  7866.     else if (*pattern == NUL)
  7867.     {
  7868.         regmatch.regprog = NULL;    /* Vim will try to free regprog later */
  7869.         no_pattern = TRUE;    /* Always matches - don't check pat. */
  7870.     }
  7871.     else
  7872.         regmatch.regprog = vim_regcomp(pattern + 1, RE_MAGIC);
  7873.     }
  7874.     else
  7875. #endif
  7876.     regmatch.regprog = vim_regcomp(pattern, RE_MAGIC);
  7877.  
  7878.     /*
  7879.      * Try for a match with the pattern with:
  7880.      * 1. the full file name, when the pattern has a '/'.
  7881.      * 2. the short file name, when the pattern has a '/'.
  7882.      * 3. the tail of the file name, when the pattern has no '/'.
  7883.      */
  7884.     if (
  7885. #ifdef FEAT_OSFILETYPE
  7886.         /* If the check is for a filetype only and we don't care
  7887.          * about the path then skip all the regexp stuff.
  7888.          */
  7889.         no_pattern ||
  7890. #endif
  7891.         (regmatch.regprog != NULL
  7892.          && ((allow_dirs
  7893.              && (vim_regexec(®match, fname, (colnr_T)0)
  7894.              || (sfname != NULL
  7895.                  && vim_regexec(®match, sfname, (colnr_T)0))))
  7896.          || (!allow_dirs && vim_regexec(®match, tail, (colnr_T)0)))))
  7897.     result = TRUE;
  7898.  
  7899.     vim_free(regmatch.regprog);
  7900.     return result;
  7901. }
  7902. #endif
  7903.  
  7904. #if defined(FEAT_WILDIGN) || defined(PROTO)
  7905. /*
  7906.  * Return TRUE if a file matches with a pattern in "list".
  7907.  * "list" is a comma-separated list of patterns, like 'wildignore'.
  7908.  * "sfname" is the short file name or NULL, "ffname" the long file name.
  7909.  */
  7910.     int
  7911. match_file_list(list, sfname, ffname)
  7912.     char_u    *list;
  7913.     char_u    *sfname;
  7914.     char_u    *ffname;
  7915. {
  7916.     char_u    buf[100];
  7917.     char_u    *tail;
  7918.     char_u    *regpat;
  7919.     char    allow_dirs;
  7920.     int        match;
  7921.     char_u    *p;
  7922.  
  7923.     tail = gettail(sfname);
  7924.  
  7925.     /* try all patterns in 'wildignore' */
  7926.     p = list;
  7927.     while (*p)
  7928.     {
  7929.     copy_option_part(&p, buf, 100, ",");
  7930.     regpat = file_pat_to_reg_pat(buf, NULL, &allow_dirs, FALSE);
  7931.     if (regpat == NULL)
  7932.         break;
  7933.     match = match_file_pat(regpat, ffname, sfname, tail, (int)allow_dirs);
  7934.     vim_free(regpat);
  7935.     if (match)
  7936.         return TRUE;
  7937.     }
  7938.     return FALSE;
  7939. }
  7940. #endif
  7941.  
  7942. /*
  7943.  * Convert the given pattern "pat" which has shell style wildcards in it, into
  7944.  * a regular expression, and return the result in allocated memory.  If there
  7945.  * is a directory path separator to be matched, then TRUE is put in
  7946.  * allow_dirs, otherwise FALSE is put there -- webb.
  7947.  * Handle backslashes before special characters, like "\*" and "\ ".
  7948.  *
  7949.  * If FEAT_OSFILETYPE defined then pass initial <type> through unchanged. Eg:
  7950.  * '<html>myfile' becomes '<html>^myfile$' -- leonard.
  7951.  *
  7952.  * Returns NULL when out of memory.
  7953.  */
  7954. /*ARGSUSED*/
  7955.     char_u *
  7956. file_pat_to_reg_pat(pat, pat_end, allow_dirs, no_bslash)
  7957.     char_u    *pat;
  7958.     char_u    *pat_end;    /* first char after pattern or NULL */
  7959.     char    *allow_dirs;    /* Result passed back out in here */
  7960.     int        no_bslash;    /* Don't use a backward slash as pathsep */
  7961. {
  7962.     int        size;
  7963.     char_u    *endp;
  7964.     char_u    *reg_pat;
  7965.     char_u    *p;
  7966.     int        i;
  7967.     int        nested = 0;
  7968.     int        add_dollar = TRUE;
  7969. #ifdef FEAT_OSFILETYPE
  7970.     int        check_length = 0;
  7971. #endif
  7972.  
  7973.     if (allow_dirs != NULL)
  7974.     *allow_dirs = FALSE;
  7975.     if (pat_end == NULL)
  7976.     pat_end = pat + STRLEN(pat);
  7977.  
  7978. #ifdef FEAT_OSFILETYPE
  7979.     /* Find out how much of the string is the filetype check */
  7980.     if (*pat == '<')
  7981.     {
  7982.     /* Count chars until the next '>' */
  7983.     for (p = pat + 1; p < pat_end && *p != '>'; p++)
  7984.         ;
  7985.     if (p < pat_end)
  7986.     {
  7987.         /* Pattern is of the form <.*>.*  */
  7988.         check_length = p - pat + 1;
  7989.         if (p + 1 >= pat_end)
  7990.         {
  7991.         /* The 'pattern' is a filetype check ONLY */
  7992.         reg_pat = (char_u *)alloc(check_length + 1);
  7993.         if (reg_pat != NULL)
  7994.         {
  7995.             mch_memmove(reg_pat, pat, (size_t)check_length);
  7996.             reg_pat[check_length] = NUL;
  7997.         }
  7998.         return reg_pat;
  7999.         }
  8000.     }
  8001.     /* else: there was no closing '>' - assume it was a normal pattern */
  8002.  
  8003.     }
  8004.     pat += check_length;
  8005.     size = 2 + check_length;
  8006. #else
  8007.     size = 2;        /* '^' at start, '$' at end */
  8008. #endif
  8009.  
  8010.     for (p = pat; p < pat_end; p++)
  8011.     {
  8012.     switch (*p)
  8013.     {
  8014.         case '*':
  8015.         case '.':
  8016.         case ',':
  8017.         case '{':
  8018.         case '}':
  8019.         case '~':
  8020.         size += 2;    /* extra backslash */
  8021.         break;
  8022. #ifdef BACKSLASH_IN_FILENAME
  8023.         case '\\':
  8024.         case '/':
  8025.         size += 4;    /* could become "[\/]" */
  8026.         break;
  8027. #endif
  8028.         default:
  8029.         size++;
  8030. # ifdef  FEAT_MBYTE
  8031.         if (enc_dbcs != 0 && (*mb_ptr2len_check)(p) > 1)
  8032.         {
  8033.             ++p;
  8034.             ++size;
  8035.         }
  8036. # endif
  8037.         break;
  8038.     }
  8039.     }
  8040.     reg_pat = alloc(size + 1);
  8041.     if (reg_pat == NULL)
  8042.     return NULL;
  8043.  
  8044. #ifdef FEAT_OSFILETYPE
  8045.     /* Copy the type check in to the start. */
  8046.     if (check_length)
  8047.     mch_memmove(reg_pat, pat - check_length, (size_t)check_length);
  8048.     i = check_length;
  8049. #else
  8050.     i = 0;
  8051. #endif
  8052.  
  8053.     if (pat[0] == '*')
  8054.     while (pat[0] == '*' && pat < pat_end - 1)
  8055.         pat++;
  8056.     else
  8057.     reg_pat[i++] = '^';
  8058.     endp = pat_end - 1;
  8059.     if (*endp == '*')
  8060.     {
  8061.     while (endp - pat > 0 && *endp == '*')
  8062.         endp--;
  8063.     add_dollar = FALSE;
  8064.     }
  8065.     for (p = pat; *p && nested >= 0 && p <= endp; p++)
  8066.     {
  8067.     switch (*p)
  8068.     {
  8069.         case '*':
  8070.         reg_pat[i++] = '.';
  8071.         reg_pat[i++] = '*';
  8072.         break;
  8073.         case '.':
  8074. #ifdef RISCOS
  8075.         if (allow_dirs != NULL)
  8076.              *allow_dirs = TRUE;
  8077.         /* FALLTHROUGH */
  8078. #endif
  8079.         case '~':
  8080.         reg_pat[i++] = '\\';
  8081.         reg_pat[i++] = *p;
  8082.         break;
  8083.         case '?':
  8084. #ifdef RISCOS
  8085.         case '#':
  8086. #endif
  8087.         reg_pat[i++] = '.';
  8088.         break;
  8089.         case '\\':
  8090.         if (p[1] == NUL)
  8091.             break;
  8092. #ifdef BACKSLASH_IN_FILENAME
  8093.         if (!no_bslash)
  8094.         {
  8095.             /* translate:
  8096.              * "\x" to "\\x"  e.g., "dir\file"
  8097.              * "\*" to "\\.*" e.g., "dir\*.c"
  8098.              * "\?" to "\\."  e.g., "dir\??.c"
  8099.              * "\+" to "\+"   e.g., "fileX\+.c"
  8100.              */
  8101.             if ((vim_isfilec(p[1]) || p[1] == '*' || p[1] == '?')
  8102.                 && p[1] != '+')
  8103.             {
  8104.             reg_pat[i++] = '[';
  8105.             reg_pat[i++] = '\\';
  8106.             reg_pat[i++] = '/';
  8107.             reg_pat[i++] = ']';
  8108.             if (allow_dirs != NULL)
  8109.                 *allow_dirs = TRUE;
  8110.             break;
  8111.             }
  8112.         }
  8113. #endif
  8114.         if (*++p == '?'
  8115. #ifdef BACKSLASH_IN_FILENAME
  8116.             && no_bslash
  8117. #endif
  8118.             )
  8119.             reg_pat[i++] = '?';
  8120.         else
  8121.             if (*p == ',')
  8122.             reg_pat[i++] = ',';
  8123.             else
  8124.             {
  8125.             if (allow_dirs != NULL && vim_ispathsep(*p)
  8126. #ifdef BACKSLASH_IN_FILENAME
  8127.                 && (!no_bslash || *p != '\\')
  8128. #endif
  8129.                 )
  8130.                 *allow_dirs = TRUE;
  8131.             reg_pat[i++] = '\\';
  8132.             reg_pat[i++] = *p;
  8133.             }
  8134.         break;
  8135. #ifdef BACKSLASH_IN_FILENAME
  8136.         case '/':
  8137.         reg_pat[i++] = '[';
  8138.         reg_pat[i++] = '\\';
  8139.         reg_pat[i++] = '/';
  8140.         reg_pat[i++] = ']';
  8141.         if (allow_dirs != NULL)
  8142.             *allow_dirs = TRUE;
  8143.         break;
  8144. #endif
  8145.         case '{':
  8146.         reg_pat[i++] = '\\';
  8147.         reg_pat[i++] = '(';
  8148.         nested++;
  8149.         break;
  8150.         case '}':
  8151.         reg_pat[i++] = '\\';
  8152.         reg_pat[i++] = ')';
  8153.         --nested;
  8154.         break;
  8155.         case ',':
  8156.         if (nested)
  8157.         {
  8158.             reg_pat[i++] = '\\';
  8159.             reg_pat[i++] = '|';
  8160.         }
  8161.         else
  8162.             reg_pat[i++] = ',';
  8163.         break;
  8164.         default:
  8165. # ifdef  FEAT_MBYTE
  8166.         if (enc_dbcs != 0 && (*mb_ptr2len_check)(p) > 1)
  8167.             reg_pat[i++] = *p++;
  8168.         else
  8169. # endif
  8170.         if (allow_dirs != NULL && vim_ispathsep(*p))
  8171.             *allow_dirs = TRUE;
  8172.         reg_pat[i++] = *p;
  8173.         break;
  8174.     }
  8175.     }
  8176.     if (add_dollar)
  8177.     reg_pat[i++] = '$';
  8178.     reg_pat[i] = NUL;
  8179.     if (nested != 0)
  8180.     {
  8181.     if (nested < 0)
  8182.         EMSG(_("E219: Missing {."));
  8183.     else
  8184.         EMSG(_("E220: Missing }."));
  8185.     vim_free(reg_pat);
  8186.     reg_pat = NULL;
  8187.     }
  8188.     return reg_pat;
  8189. }
  8190.