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