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