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