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