Mercurial > vim
annotate src/memline.c @ 32507:2614026cd259 v9.0.1585
patch 9.0.1585: weird use of static variables for spell checking
Commit: https://github.com/vim/vim/commit/30805a1aba0067cf0087f9a0e5c184562433e2e7
Author: Luuk van Baal <luukvbaal@gmail.com>
Date: Sat May 27 22:22:10 2023 +0100
patch 9.0.1585: weird use of static variables for spell checking
Problem: Weird use of static variables for spell checking.
Solution: Move the variables to a structure and pass them from win_update()
to win_line(). (Luuk van Baal, closes #12448)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 27 May 2023 23:30:03 +0200 |
parents | 5d07e7e9580f |
children | bb5458706799 |
rev | line source |
---|---|
10042
4aead6a9b7a9
commit https://github.com/vim/vim/commit/edf3f97ae2af024708ebb4ac614227327033ca47
Christian Brabandt <cb@256bit.org>
parents:
9649
diff
changeset
|
1 /* vi:set ts=8 sts=4 sw=4 noet: |
7 | 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 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
10 // for debugging |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
11 // #define CHECK(c, s) do { if (c) emsg((s)); } while (0) |
13632
cec5137d5332
patch 8.0.1688: some macros are used without a semicolon
Christian Brabandt <cb@256bit.org>
parents:
13380
diff
changeset
|
12 #define CHECK(c, s) do { /**/ } while (0) |
7 | 13 |
14 /* | |
15 * memline.c: Contains the functions for appending, deleting and changing the | |
625 | 16 * text lines. The memfile functions are used to store the information in |
17 * blocks of memory, backed up by a file. The structure of the information is | |
18 * a tree. The root of the tree is a pointer block. The leaves of the tree | |
19 * are data blocks. In between may be several layers of pointer blocks, | |
20 * forming branches. | |
7 | 21 * |
22 * Three types of blocks are used: | |
23 * - Block nr 0 contains information for recovery | |
24 * - Pointer blocks contain list of pointers to other blocks. | |
25 * - Data blocks contain the actual text. | |
26 * | |
27 * Block nr 0 contains the block0 structure (see below). | |
28 * | |
29 * Block nr 1 is the first pointer block. It is the root of the tree. | |
30 * Other pointer blocks are branches. | |
31 * | |
32 * If a line is too big to fit in a single page, the block containing that | |
33 * line is made big enough to hold the line. It may span several pages. | |
34 * Otherwise all blocks are one page. | |
35 * | |
36 * A data block that was filled when starting to edit a file and was not | |
37 * changed since then, can have a negative block number. This means that it | |
38 * has not yet been assigned a place in the file. When recovering, the lines | |
39 * in this data block can be read from the original file. When the block is | |
40 * changed (lines appended/deleted/changed) or when it is flushed it gets a | |
41 * positive number. Use mf_trans_del() to get the new number, before calling | |
42 * mf_get(). | |
43 */ | |
44 | |
45 #include "vim.h" | |
46 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
47 #ifndef UNIX // it's in os_unix.h for Unix |
7 | 48 # include <time.h> |
49 #endif | |
50 | |
1030 | 51 #if defined(SASC) || defined(__amigaos4__) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
52 # include <proto/dos.h> // for Open() and Close() |
7 | 53 #endif |
54 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
55 typedef struct block0 ZERO_BL; // contents of the first block |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
56 typedef struct pointer_block PTR_BL; // contents of a pointer block |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
57 typedef struct data_block DATA_BL; // contents of a data block |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
58 typedef struct pointer_entry PTR_EN; // block/line-count pair |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
59 |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
60 #define DATA_ID (('d' << 8) + 'a') // data block id |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
61 #define PTR_ID (('p' << 8) + 't') // pointer block id |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
62 #define BLOCK0_ID0 'b' // block 0 id 0 |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
63 #define BLOCK0_ID1 '0' // block 0 id 1 |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
64 #define BLOCK0_ID1_C0 'c' // block 0 id 1 'cm' 0 |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
65 #define BLOCK0_ID1_C1 'C' // block 0 id 1 'cm' 1 |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
66 #define BLOCK0_ID1_C2 'd' // block 0 id 1 'cm' 2 |
32503
5d07e7e9580f
patch 9.0.1583: get E304 when using 'cryptmethod' "xchacha20v2"
Bram Moolenaar <Bram@vim.org>
parents:
32325
diff
changeset
|
67 // BLOCK0_ID1_C3 and BLOCK0_ID1_C4 are for libsodium encryption. However, for |
32305
2567501acf48
patch 9.0.1484: Coverity warns for using invalid array index
Bram Moolenaar <Bram@vim.org>
parents:
32299
diff
changeset
|
68 // these the swapfile is disabled, thus they will not be used. Added for |
2567501acf48
patch 9.0.1484: Coverity warns for using invalid array index
Bram Moolenaar <Bram@vim.org>
parents:
32299
diff
changeset
|
69 // consistency anyway. |
2567501acf48
patch 9.0.1484: Coverity warns for using invalid array index
Bram Moolenaar <Bram@vim.org>
parents:
32299
diff
changeset
|
70 #define BLOCK0_ID1_C3 'S' // block 0 id 1 'cm' 3 |
2567501acf48
patch 9.0.1484: Coverity warns for using invalid array index
Bram Moolenaar <Bram@vim.org>
parents:
32299
diff
changeset
|
71 #define BLOCK0_ID1_C4 's' // block 0 id 1 'cm' 4 |
6122 | 72 |
73 #if defined(FEAT_CRYPT) | |
74 static int id1_codes[] = { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
75 BLOCK0_ID1_C0, // CRYPT_M_ZIP |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
76 BLOCK0_ID1_C1, // CRYPT_M_BF |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
77 BLOCK0_ID1_C2, // CRYPT_M_BF2 |
24970
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
78 BLOCK0_ID1_C3, // CRYPT_M_SOD - Unused! |
32305
2567501acf48
patch 9.0.1484: Coverity warns for using invalid array index
Bram Moolenaar <Bram@vim.org>
parents:
32299
diff
changeset
|
79 BLOCK0_ID1_C4, // CRYPT_M_SOD2 - Unused! |
6122 | 80 }; |
81 #endif | |
7 | 82 |
83 /* | |
84 * pointer to a block, used in a pointer block | |
85 */ | |
86 struct pointer_entry | |
87 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
88 blocknr_T pe_bnum; // block number |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
89 linenr_T pe_line_count; // number of lines in this branch |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
90 linenr_T pe_old_lnum; // lnum for this block (for recovery) |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
91 int pe_page_count; // number of pages in block pe_bnum |
7 | 92 }; |
93 | |
94 /* | |
95 * A pointer block contains a list of branches in the tree. | |
96 */ | |
97 struct pointer_block | |
98 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
99 short_u pb_id; // ID for pointer block: PTR_ID |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
100 short_u pb_count; // number of pointers in this block |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
101 short_u pb_count_max; // maximum value for pb_count |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
102 PTR_EN pb_pointer[1]; // list of pointers to blocks (actually longer) |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
103 // followed by empty space until end of page |
7 | 104 }; |
105 | |
32290
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
106 // Value for pb_count_max. |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
107 #define PB_COUNT_MAX(mfp) (short_u)(((mfp)->mf_page_size - offsetof(PTR_BL, pb_pointer)) / sizeof(PTR_EN)) |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
108 |
7 | 109 /* |
110 * A data block is a leaf in the tree. | |
111 * | |
112 * The text of the lines is at the end of the block. The text of the first line | |
113 * in the block is put at the end, the text of the second line in front of it, | |
114 * etc. Thus the order of the lines is the opposite of the line number. | |
115 */ | |
116 struct data_block | |
117 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
118 short_u db_id; // ID for data block: DATA_ID |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
119 unsigned db_free; // free space available |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
120 unsigned db_txt_start; // byte where text starts |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
121 unsigned db_txt_end; // byte just after data block |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
122 linenr_T db_line_count; // number of lines in this block |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
123 unsigned db_index[1]; // index for start of line (actually bigger) |
19195
2ef19eed524a
patch 8.2.0156: various typos in source files and tests
Bram Moolenaar <Bram@vim.org>
parents:
19133
diff
changeset
|
124 // followed by empty space up to db_txt_start |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
125 // followed by the text in the lines until |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
126 // end of page |
7 | 127 }; |
128 | |
129 /* | |
130 * The low bits of db_index hold the actual index. The topmost bit is | |
131 * used for the global command to be able to mark a line. | |
132 * This method is not clean, but otherwise there would be at least one extra | |
133 * byte used for each line. | |
134 * The mark has to be in this place to keep it with the correct line when other | |
135 * lines are inserted or deleted. | |
136 */ | |
137 #define DB_MARKED ((unsigned)1 << ((sizeof(unsigned) * 8) - 1)) | |
138 #define DB_INDEX_MASK (~DB_MARKED) | |
139 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
140 #define INDEX_SIZE (sizeof(unsigned)) // size of one db_index entry |
31877
9f28cca2410a
patch 9.0.1271: using sizeof() and subtract array size is tricky
Bram Moolenaar <Bram@vim.org>
parents:
31728
diff
changeset
|
141 #define HEADER_SIZE (offsetof(DATA_BL, db_index)) // size of data block header |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
142 |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
143 #define B0_FNAME_SIZE_ORG 900 // what it was in older versions |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
144 #define B0_FNAME_SIZE_NOCRYPT 898 // 2 bytes used for other things |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
145 #define B0_FNAME_SIZE_CRYPT 890 // 10 bytes used for other things |
39 | 146 #define B0_UNAME_SIZE 40 |
147 #define B0_HNAME_SIZE 40 | |
7 | 148 /* |
149 * Restrict the numbers to 32 bits, otherwise most compilers will complain. | |
150 * This won't detect a 64 bit machine that only swaps a byte in the top 32 | |
151 * bits, but that is crazy anyway. | |
152 */ | |
153 #define B0_MAGIC_LONG 0x30313233L | |
154 #define B0_MAGIC_INT 0x20212223L | |
155 #define B0_MAGIC_SHORT 0x10111213L | |
156 #define B0_MAGIC_CHAR 0x55 | |
157 | |
158 /* | |
159 * Block zero holds all info about the swap file. | |
160 * | |
161 * NOTE: DEFINITION OF BLOCK 0 SHOULD NOT CHANGE! It would make all existing | |
162 * swap files unusable! | |
163 * | |
164 * If size of block0 changes anyway, adjust MIN_SWAP_PAGE_SIZE in vim.h!! | |
165 * | |
1228 | 166 * This block is built up of single bytes, to make it portable across |
7 | 167 * different machines. b0_magic_* is used to check the byte order and size of |
168 * variables, because the rest of the swap file is not portable. | |
169 */ | |
170 struct block0 | |
171 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
172 char_u b0_id[2]; // id for block 0: BLOCK0_ID0 and BLOCK0_ID1, |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
173 // BLOCK0_ID1_C0, BLOCK0_ID1_C1, etc. |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
174 char_u b0_version[10]; // Vim version string |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
175 char_u b0_page_size[4];// number of bytes per page |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
176 char_u b0_mtime[4]; // last modification time of file |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
177 char_u b0_ino[4]; // inode of b0_fname |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
178 char_u b0_pid[4]; // process id of creator (or 0) |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
179 char_u b0_uname[B0_UNAME_SIZE]; // name of user (uid if no name) |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
180 char_u b0_hname[B0_HNAME_SIZE]; // host name (if it has a name) |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
181 char_u b0_fname[B0_FNAME_SIZE_ORG]; // name of file being edited |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
182 long b0_magic_long; // check for byte order of long |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
183 int b0_magic_int; // check for byte order of int |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
184 short b0_magic_short; // check for byte order of short |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
185 char_u b0_magic_char; // check for last char |
7 | 186 }; |
39 | 187 |
188 /* | |
625 | 189 * Note: b0_dirty and b0_flags are put at the end of the file name. For very |
39 | 190 * long file names in older versions of Vim they are invalid. |
191 * The 'fileencoding' comes before b0_flags, with a NUL in front. But only | |
192 * when there is room, for very long file names it's omitted. | |
193 */ | |
194 #define B0_DIRTY 0x55 | |
2267 | 195 #define b0_dirty b0_fname[B0_FNAME_SIZE_ORG - 1] |
39 | 196 |
197 /* | |
198 * The b0_flags field is new in Vim 7.0. | |
199 */ | |
2267 | 200 #define b0_flags b0_fname[B0_FNAME_SIZE_ORG - 2] |
201 | |
202 /* | |
203 * Crypt seed goes here, 8 bytes. New in Vim 7.3. | |
204 * Without encryption these bytes may be used for 'fenc'. | |
205 */ | |
206 #define b0_seed b0_fname[B0_FNAME_SIZE_ORG - 2 - MF_SEED_LEN] | |
39 | 207 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
208 // The lowest two bits contain the fileformat. Zero means it's not set |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
209 // (compatible with Vim 6.x), otherwise it's EOL_UNIX + 1, EOL_DOS + 1 or |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
210 // EOL_MAC + 1. |
39 | 211 #define B0_FF_MASK 3 |
212 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
213 // Swap file is in directory of edited file. Used to find the file from |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
214 // different mount points. |
39 | 215 #define B0_SAME_DIR 4 |
216 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
217 // The 'fileencoding' is at the end of b0_fname[], with a NUL in front of it. |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
218 // When empty there is only the NUL. |
39 | 219 #define B0_HAS_FENC 8 |
7 | 220 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
221 #define STACK_INCR 5 // nr of entries added to ml_stack at a time |
7 | 222 |
223 /* | |
224 * The line number where the first mark may be is remembered. | |
225 * If it is 0 there are no marks at all. | |
226 * (always used for the current buffer only, no buffer change possible while | |
227 * executing a global command). | |
228 */ | |
229 static linenr_T lowest_marked = 0; | |
230 | |
231 /* | |
232 * arguments for ml_find_line() | |
233 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
234 #define ML_DELETE 0x11 // delete line |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
235 #define ML_INSERT 0x12 // insert line |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
236 #define ML_FIND 0x13 // just find the line |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
237 #define ML_FLUSH 0x02 // flush locked block |
27752
c1d1639b52dd
patch 8.2.4402: missing parenthesis may cause unexpected problems
Bram Moolenaar <Bram@vim.org>
parents:
27746
diff
changeset
|
238 #define ML_SIMPLE(x) ((x) & 0x10) // DEL, INS or FIND |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
239 |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
240 // argument for ml_upd_block0() |
2267 | 241 typedef enum { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
242 UB_FNAME = 0 // update timestamp and filename |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
243 , UB_SAME_DIR // update the B0_SAME_DIR flag |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
244 , UB_CRYPT // update crypt key |
2267 | 245 } upd_block0_T; |
246 | |
247 #ifdef FEAT_CRYPT | |
7803
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
248 static void ml_set_b0_crypt(buf_T *buf, ZERO_BL *b0p); |
2267 | 249 #endif |
7803
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
250 static void ml_upd_block0(buf_T *buf, upd_block0_T what); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
251 static void set_b0_fname(ZERO_BL *, buf_T *buf); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
252 static void set_b0_dir_flag(ZERO_BL *b0p, buf_T *buf); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
253 static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
254 static time_t swapfile_info(char_u *); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
255 static int recov_file_names(char_u **, char_u *, int prepend_dot); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
256 static char_u *findswapname(buf_T *, char_u **, char_u *); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
257 static void ml_flush_line(buf_T *); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
258 static bhdr_T *ml_new_data(memfile_T *, int, int); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
259 static bhdr_T *ml_new_ptr(memfile_T *); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
260 static bhdr_T *ml_find_line(buf_T *, linenr_T, int); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
261 static int ml_add_stack(buf_T *); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
262 static void ml_lineadd(buf_T *, int); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
263 static int b0_magic_wrong(ZERO_BL *); |
7 | 264 #ifdef CHECK_INODE |
7803
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
265 static int fnamecmp_ino(char_u *, char_u *, long); |
7 | 266 #endif |
7803
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
267 static void long_to_char(long, char_u *); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
268 static long char_to_long(char_u *); |
2267 | 269 #ifdef FEAT_CRYPT |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
270 static cryptstate_T *ml_crypt_prepare(memfile_T *mfp, off_T offset, int reading); |
2267 | 271 #endif |
7 | 272 #ifdef FEAT_BYTEOFF |
7803
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7410
diff
changeset
|
273 static void ml_updatechunk(buf_T *buf, long line, long len, int updtype); |
7 | 274 #endif |
275 | |
276 /* | |
625 | 277 * Open a new memline for "buf". |
7 | 278 * |
625 | 279 * Return FAIL for failure, OK otherwise. |
7 | 280 */ |
281 int | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
282 ml_open(buf_T *buf) |
7 | 283 { |
284 memfile_T *mfp; | |
285 bhdr_T *hp = NULL; | |
286 ZERO_BL *b0p; | |
287 PTR_BL *pp; | |
288 DATA_BL *dp; | |
289 | |
625 | 290 /* |
291 * init fields in memline struct | |
292 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
293 buf->b_ml.ml_stack_size = 0; // no stack yet |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
294 buf->b_ml.ml_stack = NULL; // no stack yet |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
295 buf->b_ml.ml_stack_top = 0; // nothing in the stack |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
296 buf->b_ml.ml_locked = NULL; // no cached block |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
297 buf->b_ml.ml_line_lnum = 0; // no cached line |
7 | 298 #ifdef FEAT_BYTEOFF |
625 | 299 buf->b_ml.ml_chunksize = NULL; |
25678
4da50e168dc9
patch 8.2.3375: using uninitialized memory
Bram Moolenaar <Bram@vim.org>
parents:
25672
diff
changeset
|
300 buf->b_ml.ml_usedchunks = 0; |
7 | 301 #endif |
302 | |
22699
e82579016863
patch 8.2.1898: command modifier parsing always uses global cmdmod
Bram Moolenaar <Bram@vim.org>
parents:
22242
diff
changeset
|
303 if (cmdmod.cmod_flags & CMOD_NOSWAPFILE) |
5737 | 304 buf->b_p_swf = FALSE; |
305 | |
625 | 306 /* |
307 * When 'updatecount' is non-zero swap file may be opened later. | |
308 */ | |
309 if (p_uc && buf->b_p_swf) | |
310 buf->b_may_swap = TRUE; | |
7 | 311 else |
625 | 312 buf->b_may_swap = FALSE; |
313 | |
314 /* | |
315 * Open the memfile. No swap file is created yet. | |
316 */ | |
7 | 317 mfp = mf_open(NULL, 0); |
318 if (mfp == NULL) | |
319 goto error; | |
320 | |
625 | 321 buf->b_ml.ml_mfp = mfp; |
2267 | 322 #ifdef FEAT_CRYPT |
323 mfp->mf_buffer = buf; | |
324 #endif | |
625 | 325 buf->b_ml.ml_flags = ML_EMPTY; |
326 buf->b_ml.ml_line_count = 1; | |
7 | 327 |
328 /* | |
329 * fill block0 struct and write page 0 | |
330 */ | |
331 if ((hp = mf_new(mfp, FALSE, 1)) == NULL) | |
332 goto error; | |
333 if (hp->bh_bnum != 0) | |
334 { | |
26897
d02d40f0261c
patch 8.2.3977: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26771
diff
changeset
|
335 iemsg(_(e_didnt_get_block_nr_zero)); |
7 | 336 goto error; |
337 } | |
338 b0p = (ZERO_BL *)(hp->bh_data); | |
339 | |
340 b0p->b0_id[0] = BLOCK0_ID0; | |
341 b0p->b0_id[1] = BLOCK0_ID1; | |
342 b0p->b0_magic_long = (long)B0_MAGIC_LONG; | |
343 b0p->b0_magic_int = (int)B0_MAGIC_INT; | |
344 b0p->b0_magic_short = (short)B0_MAGIC_SHORT; | |
345 b0p->b0_magic_char = B0_MAGIC_CHAR; | |
14011
8631b54ae2a2
patch 8.1.0023: gcc 8.1 warns for use of strncpy()
Christian Brabandt <cb@256bit.org>
parents:
13896
diff
changeset
|
346 mch_memmove(b0p->b0_version, "VIM ", 4); |
7 | 347 STRNCPY(b0p->b0_version + 4, Version, 6); |
348 long_to_char((long)mfp->mf_page_size, b0p->b0_page_size); | |
625 | 349 |
800 | 350 #ifdef FEAT_SPELL |
351 if (!buf->b_spell) | |
352 #endif | |
625 | 353 { |
354 b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0; | |
355 b0p->b0_flags = get_fileformat(buf) + 1; | |
356 set_b0_fname(b0p, buf); | |
357 (void)get_user_name(b0p->b0_uname, B0_UNAME_SIZE); | |
358 b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL; | |
359 mch_get_host_name(b0p->b0_hname, B0_HNAME_SIZE); | |
360 b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL; | |
361 long_to_char(mch_get_pid(), b0p->b0_pid); | |
2267 | 362 #ifdef FEAT_CRYPT |
6122 | 363 ml_set_b0_crypt(buf, b0p); |
2267 | 364 #endif |
625 | 365 } |
7 | 366 |
367 /* | |
368 * Always sync block number 0 to disk, so we can check the file name in | |
2267 | 369 * the swap file in findswapname(). Don't do this for a help files or |
370 * a spell buffer though. | |
7 | 371 * Only works when there's a swapfile, otherwise it's done when the file |
372 * is created. | |
373 */ | |
374 mf_put(mfp, hp, TRUE, FALSE); | |
625 | 375 if (!buf->b_help && !B_SPELL(buf)) |
7 | 376 (void)mf_sync(mfp, 0); |
377 | |
625 | 378 /* |
379 * Fill in root pointer block and write page 1. | |
380 */ | |
7 | 381 if ((hp = ml_new_ptr(mfp)) == NULL) |
382 goto error; | |
383 if (hp->bh_bnum != 1) | |
384 { | |
26897
d02d40f0261c
patch 8.2.3977: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26771
diff
changeset
|
385 iemsg(_(e_didnt_get_block_nr_one)); |
7 | 386 goto error; |
387 } | |
388 pp = (PTR_BL *)(hp->bh_data); | |
389 pp->pb_count = 1; | |
390 pp->pb_pointer[0].pe_bnum = 2; | |
391 pp->pb_pointer[0].pe_page_count = 1; | |
392 pp->pb_pointer[0].pe_old_lnum = 1; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
393 pp->pb_pointer[0].pe_line_count = 1; // line count after insertion |
7 | 394 mf_put(mfp, hp, TRUE, FALSE); |
395 | |
625 | 396 /* |
397 * Allocate first data block and create an empty line 1. | |
398 */ | |
7 | 399 if ((hp = ml_new_data(mfp, FALSE, 1)) == NULL) |
400 goto error; | |
401 if (hp->bh_bnum != 2) | |
402 { | |
26897
d02d40f0261c
patch 8.2.3977: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26771
diff
changeset
|
403 iemsg(_(e_didnt_get_block_nr_two)); |
7 | 404 goto error; |
405 } | |
406 | |
407 dp = (DATA_BL *)(hp->bh_data); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
408 dp->db_index[0] = --dp->db_txt_start; // at end of block |
7 | 409 dp->db_free -= 1 + INDEX_SIZE; |
410 dp->db_line_count = 1; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
411 *((char_u *)dp + dp->db_txt_start) = NUL; // empty line |
7 | 412 |
413 return OK; | |
414 | |
415 error: | |
416 if (mfp != NULL) | |
417 { | |
418 if (hp) | |
419 mf_put(mfp, hp, FALSE, FALSE); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
420 mf_close(mfp, TRUE); // will also free(mfp->mf_fname) |
7 | 421 } |
625 | 422 buf->b_ml.ml_mfp = NULL; |
7 | 423 return FAIL; |
424 } | |
425 | |
2267 | 426 #if defined(FEAT_CRYPT) || defined(PROTO) |
427 /* | |
6130 | 428 * Prepare encryption for "buf" for the current key and method. |
429 */ | |
430 static void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
431 ml_set_mfp_crypt(buf_T *buf) |
6130 | 432 { |
31728
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
433 if (*buf->b_p_key == NUL) |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
434 return; |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
435 |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
436 int method_nr = crypt_get_method_nr(buf); |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
437 |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
438 if (method_nr > CRYPT_M_ZIP && method_nr < CRYPT_M_SOD) |
6130 | 439 { |
31728
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
440 // Generate a seed and store it in the memfile. |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
441 sha2_seed(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN, NULL, 0); |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
442 } |
24970
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
443 #ifdef FEAT_SODIUM |
32299
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
444 else if (crypt_method_is_sodium(method_nr)) |
31728
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
445 crypt_sodium_randombytes_buf(buf->b_ml.ml_mfp->mf_seed, |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
446 MF_SEED_LEN); |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
447 #endif |
6130 | 448 } |
449 | |
450 /* | |
2267 | 451 * Prepare encryption for "buf" with block 0 "b0p". |
32305
2567501acf48
patch 9.0.1484: Coverity warns for using invalid array index
Bram Moolenaar <Bram@vim.org>
parents:
32299
diff
changeset
|
452 * Note: should not be called with libsodium encryption, since xchacha20 does |
2567501acf48
patch 9.0.1484: Coverity warns for using invalid array index
Bram Moolenaar <Bram@vim.org>
parents:
32299
diff
changeset
|
453 * not support swapfile encryption. |
2267 | 454 */ |
455 static void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
456 ml_set_b0_crypt(buf_T *buf, ZERO_BL *b0p) |
2267 | 457 { |
458 if (*buf->b_p_key == NUL) | |
459 b0p->b0_id[1] = BLOCK0_ID1; | |
460 else | |
461 { | |
6122 | 462 int method_nr = crypt_get_method_nr(buf); |
463 | |
464 b0p->b0_id[1] = id1_codes[method_nr]; | |
24970
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
465 if (method_nr > CRYPT_M_ZIP && method_nr < CRYPT_M_SOD) |
2267 | 466 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
467 // Generate a seed and store it in block 0 and in the memfile. |
2267 | 468 sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0); |
469 mch_memmove(buf->b_ml.ml_mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN); | |
470 } | |
471 } | |
472 } | |
473 | |
474 /* | |
475 * Called after the crypt key or 'cryptmethod' was changed for "buf". | |
476 * Will apply this to the swapfile. | |
477 * "old_key" is the previous key. It is equal to buf->b_p_key when | |
478 * 'cryptmethod' is changed. | |
2360
d8e4b27cef80
Change 'cryptmethod' from a number to a string option. Make it global-local.
Bram Moolenaar <bram@vim.org>
parents:
2283
diff
changeset
|
479 * "old_cm" is the previous 'cryptmethod'. It is equal to the current |
d8e4b27cef80
Change 'cryptmethod' from a number to a string option. Make it global-local.
Bram Moolenaar <bram@vim.org>
parents:
2283
diff
changeset
|
480 * 'cryptmethod' when 'key' is changed. |
2267 | 481 */ |
482 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
483 ml_set_crypt_key( |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
484 buf_T *buf, |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
485 char_u *old_key, |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
486 char_u *old_cm) |
2267 | 487 { |
488 memfile_T *mfp = buf->b_ml.ml_mfp; | |
489 bhdr_T *hp; | |
490 int page_count; | |
491 int idx; | |
492 long error; | |
493 infoptr_T *ip; | |
494 PTR_BL *pp; | |
495 DATA_BL *dp; | |
496 blocknr_T bnum; | |
497 int top; | |
6817 | 498 int old_method; |
2267 | 499 |
24970
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
500 if (mfp == NULL || mfp->mf_fd < 0) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
501 return; // no memfile yet, nothing to do |
6817 | 502 old_method = crypt_method_nr_from_name(old_cm); |
503 | |
32305
2567501acf48
patch 9.0.1484: Coverity warns for using invalid array index
Bram Moolenaar <Bram@vim.org>
parents:
32299
diff
changeset
|
504 // Swapfile encryption is not supported by XChaCha20, therefore disable the |
2567501acf48
patch 9.0.1484: Coverity warns for using invalid array index
Bram Moolenaar <Bram@vim.org>
parents:
32299
diff
changeset
|
505 // swapfile to avoid plain text being written to disk. |
2567501acf48
patch 9.0.1484: Coverity warns for using invalid array index
Bram Moolenaar <Bram@vim.org>
parents:
32299
diff
changeset
|
506 if (crypt_method_is_sodium(crypt_get_method_nr(buf)) |
2567501acf48
patch 9.0.1484: Coverity warns for using invalid array index
Bram Moolenaar <Bram@vim.org>
parents:
32299
diff
changeset
|
507 && *buf->b_p_key != NUL) |
24970
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
508 { |
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
509 // close the swapfile |
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
510 mf_close_file(buf, TRUE); |
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
511 buf->b_p_swf = FALSE; |
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
512 return; |
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
513 } |
32305
2567501acf48
patch 9.0.1484: Coverity warns for using invalid array index
Bram Moolenaar <Bram@vim.org>
parents:
32299
diff
changeset
|
514 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
515 // First make sure the swapfile is in a consistent state, using the old |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
516 // key and method. |
6817 | 517 { |
518 char_u *new_key = buf->b_p_key; | |
519 char_u *new_buf_cm = buf->b_p_cm; | |
520 | |
521 buf->b_p_key = old_key; | |
522 buf->b_p_cm = old_cm; | |
523 ml_preserve(buf, FALSE); | |
524 buf->b_p_key = new_key; | |
525 buf->b_p_cm = new_buf_cm; | |
526 } | |
2267 | 527 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
528 // Set the key, method and seed to be used for reading, these must be the |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
529 // old values. |
2267 | 530 mfp->mf_old_key = old_key; |
6817 | 531 mfp->mf_old_cm = old_method; |
532 if (old_method > 0 && *old_key != NUL) | |
2267 | 533 mch_memmove(mfp->mf_old_seed, mfp->mf_seed, MF_SEED_LEN); |
534 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
535 // Update block 0 with the crypt flag and may set a new seed. |
2267 | 536 ml_upd_block0(buf, UB_CRYPT); |
537 | |
538 if (mfp->mf_infile_count > 2) | |
539 { | |
540 /* | |
541 * Need to read back all data blocks from disk, decrypt them with the | |
542 * old key/method and mark them to be written. The algorithm is | |
543 * similar to what happens in ml_recover(), but we skip negative block | |
544 * numbers. | |
545 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
546 ml_flush_line(buf); // flush buffered line |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
547 (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); // flush locked block |
2267 | 548 |
549 hp = NULL; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
550 bnum = 1; // start with block 1 |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
551 page_count = 1; // which is 1 page |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
552 idx = 0; // start with first index in block 1 |
2267 | 553 error = 0; |
554 buf->b_ml.ml_stack_top = 0; | |
13244
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
12975
diff
changeset
|
555 VIM_CLEAR(buf->b_ml.ml_stack); |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
556 buf->b_ml.ml_stack_size = 0; // no stack yet |
2267 | 557 |
558 for ( ; !got_int; line_breakcheck()) | |
559 { | |
560 if (hp != NULL) | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
561 mf_put(mfp, hp, FALSE, FALSE); // release previous block |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
562 |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
563 // get the block (pointer or data) |
27426
41e0dcf38521
patch 8.2.4241: some type casts are redundant
Bram Moolenaar <Bram@vim.org>
parents:
27231
diff
changeset
|
564 if ((hp = mf_get(mfp, bnum, page_count)) == NULL) |
2267 | 565 { |
566 if (bnum == 1) | |
567 break; | |
568 ++error; | |
569 } | |
570 else | |
571 { | |
572 pp = (PTR_BL *)(hp->bh_data); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
573 if (pp->pb_id == PTR_ID) // it is a pointer block |
2267 | 574 { |
575 if (pp->pb_count == 0) | |
576 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
577 // empty block? |
2267 | 578 ++error; |
579 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
580 else if (idx < (int)pp->pb_count) // go a block deeper |
2267 | 581 { |
582 if (pp->pb_pointer[idx].pe_bnum < 0) | |
583 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
584 // Skip data block with negative block number. |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
585 // Should not happen, because of the ml_preserve() |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
586 // above. Get same block again for next index. |
15353
21580db06cf3
patch 8.1.0684: warnings from 64-bit compiler
Bram Moolenaar <Bram@vim.org>
parents:
15294
diff
changeset
|
587 ++idx; |
2267 | 588 continue; |
589 } | |
590 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
591 // going one block deeper in the tree, new entry in |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
592 // stack |
2267 | 593 if ((top = ml_add_stack(buf)) < 0) |
594 { | |
595 ++error; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
596 break; // out of memory |
2267 | 597 } |
598 ip = &(buf->b_ml.ml_stack[top]); | |
599 ip->ip_bnum = bnum; | |
600 ip->ip_index = idx; | |
601 | |
602 bnum = pp->pb_pointer[idx].pe_bnum; | |
603 page_count = pp->pb_pointer[idx].pe_page_count; | |
6817 | 604 idx = 0; |
2267 | 605 continue; |
606 } | |
607 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
608 else // not a pointer block |
2267 | 609 { |
610 dp = (DATA_BL *)(hp->bh_data); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
611 if (dp->db_id != DATA_ID) // block id wrong |
2267 | 612 ++error; |
613 else | |
614 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
615 // It is a data block, need to write it back to disk. |
2267 | 616 mf_put(mfp, hp, TRUE, FALSE); |
617 hp = NULL; | |
618 } | |
619 } | |
620 } | |
621 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
622 if (buf->b_ml.ml_stack_top == 0) // finished |
2267 | 623 break; |
624 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
625 // go one block up in the tree |
2267 | 626 ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]); |
627 bnum = ip->ip_bnum; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
628 idx = ip->ip_index + 1; // go to next index |
2267 | 629 page_count = 1; |
630 } | |
6817 | 631 if (hp != NULL) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
632 mf_put(mfp, hp, FALSE, FALSE); // release previous block |
2657 | 633 |
634 if (error > 0) | |
26962
85866e069c24
patch 8.2.4010: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26958
diff
changeset
|
635 emsg(_(e_error_while_updating_swap_file_crypt)); |
2267 | 636 } |
637 | |
638 mfp->mf_old_key = NULL; | |
639 } | |
640 #endif | |
641 | |
7 | 642 /* |
643 * ml_setname() is called when the file name of "buf" has been changed. | |
644 * It may rename the swap file. | |
645 */ | |
646 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
647 ml_setname(buf_T *buf) |
7 | 648 { |
649 int success = FALSE; | |
650 memfile_T *mfp; | |
651 char_u *fname; | |
652 char_u *dirp; | |
8212
05b88224cea1
commit https://github.com/vim/vim/commit/48e330aff911be1c798c88a973af6437a8141fce
Christian Brabandt <cb@256bit.org>
parents:
7961
diff
changeset
|
653 #if defined(MSWIN) |
7 | 654 char_u *p; |
655 #endif | |
656 | |
657 mfp = buf->b_ml.ml_mfp; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
658 if (mfp->mf_fd < 0) // there is no swap file yet |
7 | 659 { |
660 /* | |
661 * When 'updatecount' is 0 and 'noswapfile' there is no swap file. | |
662 * For help files we will make a swap file now. | |
663 */ | |
22699
e82579016863
patch 8.2.1898: command modifier parsing always uses global cmdmod
Bram Moolenaar <Bram@vim.org>
parents:
22242
diff
changeset
|
664 if (p_uc != 0 && (cmdmod.cmod_flags & CMOD_NOSWAPFILE) == 0) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
665 ml_open_file(buf); // create a swap file |
7 | 666 return; |
667 } | |
668 | |
669 /* | |
670 * Try all directories in the 'directory' option. | |
671 */ | |
672 dirp = p_dir; | |
673 for (;;) | |
674 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
675 if (*dirp == NUL) // tried all directories, fail |
7 | 676 break; |
43 | 677 fname = findswapname(buf, &dirp, mfp->mf_fname); |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
678 // alloc's fname |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
679 if (dirp == NULL) // out of memory |
3158 | 680 break; |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
681 if (fname == NULL) // no file name found for this dir |
7 | 682 continue; |
683 | |
8212
05b88224cea1
commit https://github.com/vim/vim/commit/48e330aff911be1c798c88a973af6437a8141fce
Christian Brabandt <cb@256bit.org>
parents:
7961
diff
changeset
|
684 #if defined(MSWIN) |
7 | 685 /* |
686 * Set full pathname for swap file now, because a ":!cd dir" may | |
687 * change directory without us knowing it. | |
688 */ | |
689 p = FullName_save(fname, FALSE); | |
690 vim_free(fname); | |
691 fname = p; | |
692 if (fname == NULL) | |
693 continue; | |
694 #endif | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
695 // if the file name is the same we don't have to do anything |
7 | 696 if (fnamecmp(fname, mfp->mf_fname) == 0) |
697 { | |
698 vim_free(fname); | |
699 success = TRUE; | |
700 break; | |
701 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
702 // need to close the swap file before renaming |
7 | 703 if (mfp->mf_fd >= 0) |
704 { | |
705 close(mfp->mf_fd); | |
706 mfp->mf_fd = -1; | |
707 } | |
708 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
709 // try to rename the swap file |
7 | 710 if (vim_rename(mfp->mf_fname, fname) == 0) |
711 { | |
712 success = TRUE; | |
713 vim_free(mfp->mf_fname); | |
714 mfp->mf_fname = fname; | |
715 vim_free(mfp->mf_ffname); | |
8212
05b88224cea1
commit https://github.com/vim/vim/commit/48e330aff911be1c798c88a973af6437a8141fce
Christian Brabandt <cb@256bit.org>
parents:
7961
diff
changeset
|
716 #if defined(MSWIN) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
717 mfp->mf_ffname = NULL; // mf_fname is full pathname already |
7 | 718 #else |
719 mf_set_ffname(mfp); | |
720 #endif | |
2267 | 721 ml_upd_block0(buf, UB_SAME_DIR); |
7 | 722 break; |
723 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
724 vim_free(fname); // this fname didn't work, try another |
7 | 725 } |
726 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
727 if (mfp->mf_fd == -1) // need to (re)open the swap file |
7 | 728 { |
729 mfp->mf_fd = mch_open((char *)mfp->mf_fname, O_RDWR | O_EXTRA, 0); | |
730 if (mfp->mf_fd < 0) | |
731 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
732 // could not (re)open the swap file, what can we do???? |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
733 emsg(_(e_oops_lost_the_swap_file)); |
7 | 734 return; |
735 } | |
2003 | 736 #ifdef HAVE_FD_CLOEXEC |
737 { | |
738 int fdflags = fcntl(mfp->mf_fd, F_GETFD); | |
739 if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) | |
7961
a7e58c6e4e9a
commit https://github.com/vim/vim/commit/fbc4b4db3a9690906a96e16724350a6241cf32a5
Christian Brabandt <cb@256bit.org>
parents:
7881
diff
changeset
|
740 (void)fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC); |
2003 | 741 } |
742 #endif | |
7 | 743 } |
744 if (!success) | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
745 emsg(_(e_could_not_rename_swap_file)); |
7 | 746 } |
747 | |
748 /* | |
749 * Open a file for the memfile for all buffers that are not readonly or have | |
750 * been modified. | |
751 * Used when 'updatecount' changes from zero to non-zero. | |
752 */ | |
753 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
754 ml_open_files(void) |
7 | 755 { |
756 buf_T *buf; | |
757 | |
9649
fd9727ae3c49
commit https://github.com/vim/vim/commit/2932359000b2f918d5fade79ea4d124d5943cd07
Christian Brabandt <cb@256bit.org>
parents:
9536
diff
changeset
|
758 FOR_ALL_BUFFERS(buf) |
7 | 759 if (!buf->b_p_ro || buf->b_changed) |
760 ml_open_file(buf); | |
761 } | |
762 | |
763 /* | |
764 * Open a swap file for an existing memfile, if there is no swap file yet. | |
765 * If we are unable to find a file name, mf_fname will be NULL | |
766 * and the memfile will be in memory only (no recovery possible). | |
767 */ | |
768 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
769 ml_open_file(buf_T *buf) |
7 | 770 { |
771 memfile_T *mfp; | |
772 char_u *fname; | |
773 char_u *dirp; | |
774 | |
775 mfp = buf->b_ml.ml_mfp; | |
22699
e82579016863
patch 8.2.1898: command modifier parsing always uses global cmdmod
Bram Moolenaar <Bram@vim.org>
parents:
22242
diff
changeset
|
776 if (mfp == NULL || mfp->mf_fd >= 0 || !buf->b_p_swf |
e82579016863
patch 8.2.1898: command modifier parsing always uses global cmdmod
Bram Moolenaar <Bram@vim.org>
parents:
22242
diff
changeset
|
777 || (cmdmod.cmod_flags & CMOD_NOSWAPFILE)) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
778 return; // nothing to do |
7 | 779 |
748 | 780 #ifdef FEAT_SPELL |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
781 // For a spell buffer use a temp file name. |
625 | 782 if (buf->b_spell) |
783 { | |
6721 | 784 fname = vim_tempname('s', FALSE); |
625 | 785 if (fname != NULL) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
786 (void)mf_open_file(mfp, fname); // consumes fname! |
625 | 787 buf->b_may_swap = FALSE; |
788 return; | |
789 } | |
790 #endif | |
791 | |
7 | 792 /* |
793 * Try all directories in 'directory' option. | |
794 */ | |
795 dirp = p_dir; | |
796 for (;;) | |
797 { | |
798 if (*dirp == NUL) | |
799 break; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
800 // There is a small chance that between choosing the swap file name |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
801 // and creating it, another Vim creates the file. In that case the |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
802 // creation will fail and we will use another directory. |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
803 fname = findswapname(buf, &dirp, NULL); // allocates fname |
3158 | 804 if (dirp == NULL) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
805 break; // out of memory |
7 | 806 if (fname == NULL) |
807 continue; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
808 if (mf_open_file(mfp, fname) == OK) // consumes fname! |
7 | 809 { |
32503
5d07e7e9580f
patch 9.0.1583: get E304 when using 'cryptmethod' "xchacha20v2"
Bram Moolenaar <Bram@vim.org>
parents:
32325
diff
changeset
|
810 // don't sync yet in ml_sync_all() |
5d07e7e9580f
patch 9.0.1583: get E304 when using 'cryptmethod' "xchacha20v2"
Bram Moolenaar <Bram@vim.org>
parents:
32325
diff
changeset
|
811 mfp->mf_dirty = MF_DIRTY_YES_NOSYNC; |
8212
05b88224cea1
commit https://github.com/vim/vim/commit/48e330aff911be1c798c88a973af6437a8141fce
Christian Brabandt <cb@256bit.org>
parents:
7961
diff
changeset
|
812 #if defined(MSWIN) |
7 | 813 /* |
814 * set full pathname for swap file now, because a ":!cd dir" may | |
815 * change directory without us knowing it. | |
816 */ | |
817 mf_fullname(mfp); | |
818 #endif | |
2267 | 819 ml_upd_block0(buf, UB_SAME_DIR); |
39 | 820 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
821 // Flush block zero, so others can read it |
7 | 822 if (mf_sync(mfp, MFS_ZERO) == OK) |
630 | 823 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
824 // Mark all blocks that should be in the swapfile as dirty. |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
825 // Needed for when the 'swapfile' option was reset, so that |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
826 // the swap file was deleted, and then on again. |
630 | 827 mf_set_dirty(mfp); |
7 | 828 break; |
630 | 829 } |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
830 // Writing block 0 failed: close the file and try another dir |
7 | 831 mf_close_file(buf, FALSE); |
832 } | |
833 } | |
834 | |
18372
11394af51615
patch 8.1.2180: Error E303 is not useful when 'directory' is empty
Bram Moolenaar <Bram@vim.org>
parents:
18139
diff
changeset
|
835 if (*p_dir != NUL && mfp->mf_fname == NULL) |
7 | 836 { |
29960
4fcf816aa806
patch 9.0.0318: clearing screen causes flicker
Bram Moolenaar <Bram@vim.org>
parents:
29940
diff
changeset
|
837 need_wait_return = TRUE; // call wait_return() later |
7 | 838 ++no_wait_return; |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
839 (void)semsg(_(e_unable_to_open_swap_file_for_str_recovery_impossible), |
3839 | 840 buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname); |
7 | 841 --no_wait_return; |
842 } | |
843 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
844 // don't try to open a swap file again |
7 | 845 buf->b_may_swap = FALSE; |
846 } | |
847 | |
848 /* | |
849 * If still need to create a swap file, and starting to edit a not-readonly | |
850 * file, or reading into an existing buffer, create a swap file now. | |
851 */ | |
852 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
853 check_need_swap( |
14593
b6b2f7d69c7f
patch 8.1.0310: file info msg not always suppressed with 'F' in 'shortmess'
Christian Brabandt <cb@256bit.org>
parents:
14579
diff
changeset
|
854 int newfile) // reading file into new buffer |
7 | 855 { |
14593
b6b2f7d69c7f
patch 8.1.0310: file info msg not always suppressed with 'F' in 'shortmess'
Christian Brabandt <cb@256bit.org>
parents:
14579
diff
changeset
|
856 int old_msg_silent = msg_silent; // might be reset by an E325 message |
b6b2f7d69c7f
patch 8.1.0310: file info msg not always suppressed with 'F' in 'shortmess'
Christian Brabandt <cb@256bit.org>
parents:
14579
diff
changeset
|
857 |
7 | 858 if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile)) |
859 ml_open_file(curbuf); | |
14593
b6b2f7d69c7f
patch 8.1.0310: file info msg not always suppressed with 'F' in 'shortmess'
Christian Brabandt <cb@256bit.org>
parents:
14579
diff
changeset
|
860 msg_silent = old_msg_silent; |
7 | 861 } |
862 | |
863 /* | |
864 * Close memline for buffer 'buf'. | |
865 * If 'del_file' is TRUE, delete the swap file | |
866 */ | |
867 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
868 ml_close(buf_T *buf, int del_file) |
7 | 869 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
870 if (buf->b_ml.ml_mfp == NULL) // not open |
7 | 871 return; |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
872 mf_close(buf->b_ml.ml_mfp, del_file); // close the .swp file |
29340
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
873 if (buf->b_ml.ml_line_lnum != 0 |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
874 && (buf->b_ml.ml_flags & (ML_LINE_DIRTY | ML_ALLOCATED))) |
7 | 875 vim_free(buf->b_ml.ml_line_ptr); |
876 vim_free(buf->b_ml.ml_stack); | |
877 #ifdef FEAT_BYTEOFF | |
13244
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
12975
diff
changeset
|
878 VIM_CLEAR(buf->b_ml.ml_chunksize); |
7 | 879 #endif |
880 buf->b_ml.ml_mfp = NULL; | |
881 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
882 // Reset the "recovered" flag, give the ATTENTION prompt the next time |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
883 // this buffer is loaded. |
7 | 884 buf->b_flags &= ~BF_RECOVERED; |
885 } | |
886 | |
887 /* | |
888 * Close all existing memlines and memfiles. | |
889 * Only used when exiting. | |
890 * When 'del_file' is TRUE, delete the memfiles. | |
165 | 891 * But don't delete files that were ":preserve"d when we are POSIX compatible. |
7 | 892 */ |
893 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
894 ml_close_all(int del_file) |
7 | 895 { |
896 buf_T *buf; | |
897 | |
9649
fd9727ae3c49
commit https://github.com/vim/vim/commit/2932359000b2f918d5fade79ea4d124d5943cd07
Christian Brabandt <cb@256bit.org>
parents:
9536
diff
changeset
|
898 FOR_ALL_BUFFERS(buf) |
165 | 899 ml_close(buf, del_file && ((buf->b_flags & BF_PRESERVED) == 0 |
900 || vim_strchr(p_cpo, CPO_PRESERVE) == NULL)); | |
5519 | 901 #ifdef FEAT_SPELL |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
902 spell_delete_wordlist(); // delete the internal wordlist |
5519 | 903 #endif |
7 | 904 #ifdef TEMPDIRNAMES |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
905 vim_deltempdir(); // delete created temp directory |
7 | 906 #endif |
907 } | |
908 | |
909 /* | |
910 * Close all memfiles for not modified buffers. | |
911 * Only use just before exiting! | |
912 */ | |
913 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
914 ml_close_notmod(void) |
7 | 915 { |
916 buf_T *buf; | |
917 | |
9649
fd9727ae3c49
commit https://github.com/vim/vim/commit/2932359000b2f918d5fade79ea4d124d5943cd07
Christian Brabandt <cb@256bit.org>
parents:
9536
diff
changeset
|
918 FOR_ALL_BUFFERS(buf) |
7 | 919 if (!bufIsChanged(buf)) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
920 ml_close(buf, TRUE); // close all not-modified buffers |
7 | 921 } |
922 | |
923 /* | |
924 * Update the timestamp in the .swp file. | |
925 * Used when the file has been written. | |
926 */ | |
927 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
928 ml_timestamp(buf_T *buf) |
7 | 929 { |
2267 | 930 ml_upd_block0(buf, UB_FNAME); |
931 } | |
932 | |
933 /* | |
934 * Return FAIL when the ID of "b0p" is wrong. | |
935 */ | |
936 static int | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
937 ml_check_b0_id(ZERO_BL *b0p) |
2267 | 938 { |
939 if (b0p->b0_id[0] != BLOCK0_ID0 | |
940 || (b0p->b0_id[1] != BLOCK0_ID1 | |
941 && b0p->b0_id[1] != BLOCK0_ID1_C0 | |
6122 | 942 && b0p->b0_id[1] != BLOCK0_ID1_C1 |
24970
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
943 && b0p->b0_id[1] != BLOCK0_ID1_C2 |
32503
5d07e7e9580f
patch 9.0.1583: get E304 when using 'cryptmethod' "xchacha20v2"
Bram Moolenaar <Bram@vim.org>
parents:
32325
diff
changeset
|
944 && b0p->b0_id[1] != BLOCK0_ID1_C3 |
5d07e7e9580f
patch 9.0.1583: get E304 when using 'cryptmethod' "xchacha20v2"
Bram Moolenaar <Bram@vim.org>
parents:
32325
diff
changeset
|
945 && b0p->b0_id[1] != BLOCK0_ID1_C4) |
2267 | 946 ) |
947 return FAIL; | |
948 return OK; | |
39 | 949 } |
950 | |
951 /* | |
952 * Update the timestamp or the B0_SAME_DIR flag of the .swp file. | |
953 */ | |
954 static void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
955 ml_upd_block0(buf_T *buf, upd_block0_T what) |
39 | 956 { |
7 | 957 memfile_T *mfp; |
958 bhdr_T *hp; | |
959 ZERO_BL *b0p; | |
960 | |
961 mfp = buf->b_ml.ml_mfp; | |
6130 | 962 if (mfp == NULL) |
7 | 963 return; |
6130 | 964 hp = mf_get(mfp, (blocknr_T)0, 1); |
965 if (hp == NULL) | |
966 { | |
967 #ifdef FEAT_CRYPT | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
968 // Possibly update the seed in the memfile before there is a block0. |
6130 | 969 if (what == UB_CRYPT) |
970 ml_set_mfp_crypt(buf); | |
971 #endif | |
972 return; | |
973 } | |
974 | |
7 | 975 b0p = (ZERO_BL *)(hp->bh_data); |
2267 | 976 if (ml_check_b0_id(b0p) == FAIL) |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
977 iemsg(_(e_ml_upd_block0_didnt_get_block_zero)); |
7 | 978 else |
39 | 979 { |
2267 | 980 if (what == UB_FNAME) |
39 | 981 set_b0_fname(b0p, buf); |
2267 | 982 #ifdef FEAT_CRYPT |
983 else if (what == UB_CRYPT) | |
984 ml_set_b0_crypt(buf, b0p); | |
985 #endif | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
986 else // what == UB_SAME_DIR |
39 | 987 set_b0_dir_flag(b0p, buf); |
988 } | |
7 | 989 mf_put(mfp, hp, TRUE, FALSE); |
990 } | |
991 | |
992 /* | |
993 * Write file name and timestamp into block 0 of a swap file. | |
994 * Also set buf->b_mtime. | |
995 * Don't use NameBuff[]!!! | |
996 */ | |
997 static void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
998 set_b0_fname(ZERO_BL *b0p, buf_T *buf) |
7 | 999 { |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
1000 stat_T st; |
7 | 1001 |
1002 if (buf->b_ffname == NULL) | |
1003 b0p->b0_fname[0] = NUL; | |
1004 else | |
1005 { | |
8212
05b88224cea1
commit https://github.com/vim/vim/commit/48e330aff911be1c798c88a973af6437a8141fce
Christian Brabandt <cb@256bit.org>
parents:
7961
diff
changeset
|
1006 #if defined(MSWIN) || defined(AMIGA) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1007 // Systems that cannot translate "~user" back into a path: copy the |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1008 // file name unmodified. Do use slashes instead of backslashes for |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1009 // portability. |
2267 | 1010 vim_strncpy(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE_CRYPT - 1); |
39 | 1011 # ifdef BACKSLASH_IN_FILENAME |
1012 forward_slash(b0p->b0_fname); | |
1013 # endif | |
7 | 1014 #else |
1015 size_t flen, ulen; | |
1016 char_u uname[B0_UNAME_SIZE]; | |
1017 | |
1018 /* | |
1019 * For a file under the home directory of the current user, we try to | |
1020 * replace the home directory path with "~user". This helps when | |
1021 * editing the same file on different machines over a network. | |
1022 * First replace home dir path with "~/" with home_replace(). | |
1023 * Then insert the user name to get "~user/". | |
1024 */ | |
2267 | 1025 home_replace(NULL, buf->b_ffname, b0p->b0_fname, |
1026 B0_FNAME_SIZE_CRYPT, TRUE); | |
7 | 1027 if (b0p->b0_fname[0] == '~') |
1028 { | |
1029 flen = STRLEN(b0p->b0_fname); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1030 // If there is no user name or it is too long, don't use "~/" |
7 | 1031 if (get_user_name(uname, B0_UNAME_SIZE) == FAIL |
2267 | 1032 || (ulen = STRLEN(uname)) + flen > B0_FNAME_SIZE_CRYPT - 1) |
1033 vim_strncpy(b0p->b0_fname, buf->b_ffname, | |
1034 B0_FNAME_SIZE_CRYPT - 1); | |
7 | 1035 else |
1036 { | |
1037 mch_memmove(b0p->b0_fname + ulen + 1, b0p->b0_fname + 1, flen); | |
1038 mch_memmove(b0p->b0_fname + 1, uname, ulen); | |
1039 } | |
1040 } | |
1041 #endif | |
1042 if (mch_stat((char *)buf->b_ffname, &st) >= 0) | |
1043 { | |
1044 long_to_char((long)st.st_mtime, b0p->b0_mtime); | |
1045 #ifdef CHECK_INODE | |
1046 long_to_char((long)st.st_ino, b0p->b0_ino); | |
1047 #endif | |
1048 buf_store_time(buf, &st, buf->b_ffname); | |
1049 buf->b_mtime_read = buf->b_mtime; | |
25953
d7e1cf30728c
patch 8.2.3510: changes are only detected with one second accuracy
Bram Moolenaar <Bram@vim.org>
parents:
25913
diff
changeset
|
1050 buf->b_mtime_read_ns = buf->b_mtime_ns; |
7 | 1051 } |
1052 else | |
1053 { | |
1054 long_to_char(0L, b0p->b0_mtime); | |
1055 #ifdef CHECK_INODE | |
1056 long_to_char(0L, b0p->b0_ino); | |
1057 #endif | |
1058 buf->b_mtime = 0; | |
25953
d7e1cf30728c
patch 8.2.3510: changes are only detected with one second accuracy
Bram Moolenaar <Bram@vim.org>
parents:
25913
diff
changeset
|
1059 buf->b_mtime_ns = 0; |
7 | 1060 buf->b_mtime_read = 0; |
25953
d7e1cf30728c
patch 8.2.3510: changes are only detected with one second accuracy
Bram Moolenaar <Bram@vim.org>
parents:
25913
diff
changeset
|
1061 buf->b_mtime_read_ns = 0; |
7 | 1062 buf->b_orig_size = 0; |
1063 buf->b_orig_mode = 0; | |
1064 } | |
1065 } | |
39 | 1066 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1067 // Also add the 'fileencoding' if there is room. |
39 | 1068 add_b0_fenc(b0p, curbuf); |
7 | 1069 } |
1070 | |
1071 /* | |
39 | 1072 * Update the B0_SAME_DIR flag of the swap file. It's set if the file and the |
1073 * swapfile for "buf" are in the same directory. | |
1074 * This is fail safe: if we are not sure the directories are equal the flag is | |
1075 * not set. | |
1076 */ | |
1077 static void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1078 set_b0_dir_flag(ZERO_BL *b0p, buf_T *buf) |
39 | 1079 { |
1080 if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname)) | |
1081 b0p->b0_flags |= B0_SAME_DIR; | |
1082 else | |
1083 b0p->b0_flags &= ~B0_SAME_DIR; | |
1084 } | |
1085 | |
1086 /* | |
1087 * When there is room, add the 'fileencoding' to block zero. | |
1088 */ | |
1089 static void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1090 add_b0_fenc( |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1091 ZERO_BL *b0p, |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1092 buf_T *buf) |
39 | 1093 { |
1094 int n; | |
2267 | 1095 int size = B0_FNAME_SIZE_NOCRYPT; |
1096 | |
15597
536dd2bc5ac9
patch 8.1.0806: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15543
diff
changeset
|
1097 #ifdef FEAT_CRYPT |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1098 // Without encryption use the same offset as in Vim 7.2 to be compatible. |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1099 // With encryption it's OK to move elsewhere, the swap file is not |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1100 // compatible anyway. |
2267 | 1101 if (*buf->b_p_key != NUL) |
1102 size = B0_FNAME_SIZE_CRYPT; | |
15597
536dd2bc5ac9
patch 8.1.0806: too many #ifdefs
Bram Moolenaar <Bram@vim.org>
parents:
15543
diff
changeset
|
1103 #endif |
39 | 1104 |
835 | 1105 n = (int)STRLEN(buf->b_p_fenc); |
2267 | 1106 if ((int)STRLEN(b0p->b0_fname) + n + 1 > size) |
39 | 1107 b0p->b0_flags &= ~B0_HAS_FENC; |
1108 else | |
1109 { | |
2267 | 1110 mch_memmove((char *)b0p->b0_fname + size - n, |
39 | 1111 (char *)buf->b_p_fenc, (size_t)n); |
2267 | 1112 *(b0p->b0_fname + size - n - 1) = NUL; |
39 | 1113 b0p->b0_flags |= B0_HAS_FENC; |
1114 } | |
1115 } | |
1116 | |
24089
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1117 #if defined(HAVE_SYS_SYSINFO_H) && defined(HAVE_SYSINFO_UPTIME) |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1118 # include <sys/sysinfo.h> |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1119 #endif |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1120 |
25155
a37cf57980f9
patch 8.2.3114: Amiga-like systems: build error using stat()
Bram Moolenaar <Bram@vim.org>
parents:
25050
diff
changeset
|
1121 #if defined(UNIX) || defined(MSWIN) |
24089
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1122 /* |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1123 * Return TRUE if the process with number "b0p->b0_pid" is still running. |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1124 * "swap_fname" is the name of the swap file, if it's from before a reboot then |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1125 * the result is FALSE; |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1126 */ |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1127 static int |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1128 swapfile_process_running(ZERO_BL *b0p, char_u *swap_fname UNUSED) |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1129 { |
25899
076f9b8e9632
patch 8.2.3483: #ifdef for using sysinfo() is incomplete
Bram Moolenaar <Bram@vim.org>
parents:
25678
diff
changeset
|
1130 #if defined(HAVE_SYSINFO) && defined(HAVE_SYSINFO_UPTIME) |
24089
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1131 stat_T st; |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1132 struct sysinfo sinfo; |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1133 |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1134 // If the system rebooted after when the swap file was written then the |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1135 // process can't be running now. |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1136 if (mch_stat((char *)swap_fname, &st) != -1 |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1137 && sysinfo(&sinfo) == 0 |
24093
5dfee9b1eabe
patch 8.2.2588: build failure with tiny features
Bram Moolenaar <Bram@vim.org>
parents:
24089
diff
changeset
|
1138 && st.st_mtime < time(NULL) - ( |
25155
a37cf57980f9
patch 8.2.3114: Amiga-like systems: build error using stat()
Bram Moolenaar <Bram@vim.org>
parents:
25050
diff
changeset
|
1139 # ifdef FEAT_EVAL |
24093
5dfee9b1eabe
patch 8.2.2588: build failure with tiny features
Bram Moolenaar <Bram@vim.org>
parents:
24089
diff
changeset
|
1140 override_sysinfo_uptime >= 0 ? override_sysinfo_uptime : |
25155
a37cf57980f9
patch 8.2.3114: Amiga-like systems: build error using stat()
Bram Moolenaar <Bram@vim.org>
parents:
25050
diff
changeset
|
1141 # endif |
24093
5dfee9b1eabe
patch 8.2.2588: build failure with tiny features
Bram Moolenaar <Bram@vim.org>
parents:
24089
diff
changeset
|
1142 sinfo.uptime)) |
24089
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1143 return FALSE; |
25155
a37cf57980f9
patch 8.2.3114: Amiga-like systems: build error using stat()
Bram Moolenaar <Bram@vim.org>
parents:
25050
diff
changeset
|
1144 # endif |
24089
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1145 return mch_process_running(char_to_long(b0p->b0_pid)); |
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1146 } |
25155
a37cf57980f9
patch 8.2.3114: Amiga-like systems: build error using stat()
Bram Moolenaar <Bram@vim.org>
parents:
25050
diff
changeset
|
1147 #endif |
39 | 1148 |
1149 /* | |
2267 | 1150 * Try to recover curbuf from the .swp file. |
16738
b52ea9c5f1db
patch 8.1.1371: cannot recover from a swap file
Bram Moolenaar <Bram@vim.org>
parents:
16684
diff
changeset
|
1151 * If "checkext" is TRUE, check the extension and detect whether it is |
b52ea9c5f1db
patch 8.1.1371: cannot recover from a swap file
Bram Moolenaar <Bram@vim.org>
parents:
16684
diff
changeset
|
1152 * a swap file. |
7 | 1153 */ |
1154 void | |
16738
b52ea9c5f1db
patch 8.1.1371: cannot recover from a swap file
Bram Moolenaar <Bram@vim.org>
parents:
16684
diff
changeset
|
1155 ml_recover(int checkext) |
7 | 1156 { |
1157 buf_T *buf = NULL; | |
1158 memfile_T *mfp = NULL; | |
1159 char_u *fname; | |
2267 | 1160 char_u *fname_used = NULL; |
7 | 1161 bhdr_T *hp = NULL; |
1162 ZERO_BL *b0p; | |
39 | 1163 int b0_ff; |
1164 char_u *b0_fenc = NULL; | |
2267 | 1165 #ifdef FEAT_CRYPT |
1166 int b0_cm = -1; | |
1167 #endif | |
7 | 1168 PTR_BL *pp; |
1169 DATA_BL *dp; | |
1170 infoptr_T *ip; | |
1171 blocknr_T bnum; | |
1172 int page_count; | |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
1173 stat_T org_stat, swp_stat; |
7 | 1174 int len; |
1175 int directly; | |
1176 linenr_T lnum; | |
1177 char_u *p; | |
1178 int i; | |
1179 long error; | |
1180 int cannot_open; | |
1181 linenr_T line_count; | |
1182 int has_error; | |
1183 int idx; | |
1184 int top; | |
1185 int txt_start; | |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
1186 off_T size; |
7 | 1187 int called_from_main; |
1188 int serious_error = TRUE; | |
1189 long mtime; | |
1190 int attr; | |
2162
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1191 int orig_file_status = NOTDONE; |
7 | 1192 |
1193 recoverymode = TRUE; | |
1194 called_from_main = (curbuf->b_ml.ml_mfp == NULL); | |
11158
501f46f7644c
patch 8.0.0466: still macros that should be all-caps
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
1195 attr = HL_ATTR(HLF_E); |
1975 | 1196 |
1197 /* | |
12975
e311187347c1
patch 8.0.1363: recovering does not work when swap file ends in .stz
Christian Brabandt <cb@256bit.org>
parents:
12477
diff
changeset
|
1198 * If the file name ends in ".s[a-w][a-z]" we assume this is the swap file. |
1975 | 1199 * Otherwise a search is done to find the swap file(s). |
1200 */ | |
7 | 1201 fname = curbuf->b_fname; |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1202 if (fname == NULL) // When there is no file name |
7 | 1203 fname = (char_u *)""; |
1204 len = (int)STRLEN(fname); | |
16738
b52ea9c5f1db
patch 8.1.1371: cannot recover from a swap file
Bram Moolenaar <Bram@vim.org>
parents:
16684
diff
changeset
|
1205 if (checkext && len >= 4 && |
2823 | 1206 #if defined(VMS) |
10889
5780bd3a5a7e
patch 8.0.0334: can't access b:changedtick from a dict reference
Christian Brabandt <cb@256bit.org>
parents:
10575
diff
changeset
|
1207 STRNICMP(fname + len - 4, "_s", 2) |
7 | 1208 #else |
10889
5780bd3a5a7e
patch 8.0.0334: can't access b:changedtick from a dict reference
Christian Brabandt <cb@256bit.org>
parents:
10575
diff
changeset
|
1209 STRNICMP(fname + len - 4, ".s", 2) |
7 | 1210 #endif |
10889
5780bd3a5a7e
patch 8.0.0334: can't access b:changedtick from a dict reference
Christian Brabandt <cb@256bit.org>
parents:
10575
diff
changeset
|
1211 == 0 |
12975
e311187347c1
patch 8.0.1363: recovering does not work when swap file ends in .stz
Christian Brabandt <cb@256bit.org>
parents:
12477
diff
changeset
|
1212 && vim_strchr((char_u *)"abcdefghijklmnopqrstuvw", |
e311187347c1
patch 8.0.1363: recovering does not work when swap file ends in .stz
Christian Brabandt <cb@256bit.org>
parents:
12477
diff
changeset
|
1213 TOLOWER_ASC(fname[len - 2])) != NULL |
1975 | 1214 && ASCII_ISALPHA(fname[len - 1])) |
7 | 1215 { |
1216 directly = TRUE; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1217 fname_used = vim_strsave(fname); // make a copy for mf_open() |
7 | 1218 } |
1219 else | |
1220 { | |
1221 directly = FALSE; | |
1222 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1223 // count the number of matching swap files |
31347
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
1224 len = recover_names(fname, FALSE, NULL, 0, NULL); |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1225 if (len == 0) // no swap files found |
7 | 1226 { |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
1227 semsg(_(e_no_swap_file_found_for_str), fname); |
7 | 1228 goto theend; |
1229 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1230 if (len == 1) // one swap file found, use it |
7 | 1231 i = 1; |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1232 else // several swap files found, choose |
7 | 1233 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1234 // list the names of the swap files |
31347
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
1235 (void)recover_names(fname, TRUE, NULL, 0, NULL); |
7 | 1236 msg_putchar('\n'); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1237 msg_puts(_("Enter number of swap file to use (0 to quit): ")); |
374 | 1238 i = get_number(FALSE, NULL); |
7 | 1239 if (i < 1 || i > len) |
1240 goto theend; | |
1241 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1242 // get the swap file name that will be used |
31347
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
1243 (void)recover_names(fname, FALSE, NULL, i, &fname_used); |
7 | 1244 } |
2267 | 1245 if (fname_used == NULL) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1246 goto theend; // out of memory |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1247 |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1248 // When called from main() still need to initialize storage structure |
625 | 1249 if (called_from_main && ml_open(curbuf) == FAIL) |
7 | 1250 getout(1); |
1251 | |
2267 | 1252 /* |
1253 * Allocate a buffer structure for the swap file that is used for recovery. | |
2407
6bc102a4bff8
Fix memory access to 'cryptmethod' during recovery. (Dominique Pelle)
Bram Moolenaar <bram@vim.org>
parents:
2394
diff
changeset
|
1254 * Only the memline and crypt information in it are really used. |
2267 | 1255 */ |
16825
ce04ebdf26b8
patch 8.1.1414: alloc() returning "char_u *" causes a lot of type casts
Bram Moolenaar <Bram@vim.org>
parents:
16786
diff
changeset
|
1256 buf = ALLOC_ONE(buf_T); |
7 | 1257 if (buf == NULL) |
1258 goto theend; | |
2267 | 1259 |
1260 /* | |
1261 * init fields in memline struct | |
1262 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1263 buf->b_ml.ml_stack_size = 0; // no stack yet |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1264 buf->b_ml.ml_stack = NULL; // no stack yet |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1265 buf->b_ml.ml_stack_top = 0; // nothing in the stack |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1266 buf->b_ml.ml_line_lnum = 0; // no cached line |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1267 buf->b_ml.ml_locked = NULL; // no locked block |
7 | 1268 buf->b_ml.ml_flags = 0; |
2408
9e2e63af1641
Better fix for memory access in recovery. (Dominique Pelle)
Bram Moolenaar <bram@vim.org>
parents:
2407
diff
changeset
|
1269 #ifdef FEAT_CRYPT |
9e2e63af1641
Better fix for memory access in recovery. (Dominique Pelle)
Bram Moolenaar <bram@vim.org>
parents:
2407
diff
changeset
|
1270 buf->b_p_key = empty_option; |
9e2e63af1641
Better fix for memory access in recovery. (Dominique Pelle)
Bram Moolenaar <bram@vim.org>
parents:
2407
diff
changeset
|
1271 buf->b_p_cm = empty_option; |
9e2e63af1641
Better fix for memory access in recovery. (Dominique Pelle)
Bram Moolenaar <bram@vim.org>
parents:
2407
diff
changeset
|
1272 #endif |
7 | 1273 |
2267 | 1274 /* |
1275 * open the memfile from the old swap file | |
1276 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1277 p = vim_strsave(fname_used); // save "fname_used" for the message: |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1278 // mf_open() will consume "fname_used"! |
2267 | 1279 mfp = mf_open(fname_used, O_RDONLY); |
1280 fname_used = p; | |
7 | 1281 if (mfp == NULL || mfp->mf_fd < 0) |
1282 { | |
2267 | 1283 if (fname_used != NULL) |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
1284 semsg(_(e_cannot_open_str), fname_used); |
7 | 1285 goto theend; |
1286 } | |
1287 buf->b_ml.ml_mfp = mfp; | |
2267 | 1288 #ifdef FEAT_CRYPT |
1289 mfp->mf_buffer = buf; | |
1290 #endif | |
7 | 1291 |
1292 /* | |
1293 * The page size set in mf_open() might be different from the page size | |
1294 * used in the swap file, we must get it from block 0. But to read block | |
1295 * 0 we need a page size. Use the minimal size for block 0 here, it will | |
1296 * be set to the real value below. | |
1297 */ | |
1298 mfp->mf_page_size = MIN_SWAP_PAGE_SIZE; | |
1299 | |
2267 | 1300 /* |
1301 * try to read block 0 | |
1302 */ | |
7 | 1303 if ((hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL) |
1304 { | |
1305 msg_start(); | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1306 msg_puts_attr(_("Unable to read block 0 from "), attr | MSG_HIST); |
7 | 1307 msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1308 msg_puts_attr(_("\nMaybe no changes were made or Vim did not update the swap file."), |
7 | 1309 attr | MSG_HIST); |
1310 msg_end(); | |
1311 goto theend; | |
1312 } | |
1313 b0p = (ZERO_BL *)(hp->bh_data); | |
1314 if (STRNCMP(b0p->b0_version, "VIM 3.0", 7) == 0) | |
1315 { | |
1316 msg_start(); | |
1317 msg_outtrans_attr(mfp->mf_fname, MSG_HIST); | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1318 msg_puts_attr(_(" cannot be used with this version of Vim.\n"), |
7 | 1319 MSG_HIST); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1320 msg_puts_attr(_("Use Vim version 3.0.\n"), MSG_HIST); |
7 | 1321 msg_end(); |
1322 goto theend; | |
1323 } | |
2267 | 1324 if (ml_check_b0_id(b0p) == FAIL) |
7 | 1325 { |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
1326 semsg(_(e_str_does_not_look_like_vim_swap_file), mfp->mf_fname); |
7 | 1327 goto theend; |
1328 } | |
1329 if (b0_magic_wrong(b0p)) | |
1330 { | |
1331 msg_start(); | |
1332 msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST); | |
8212
05b88224cea1
commit https://github.com/vim/vim/commit/48e330aff911be1c798c88a973af6437a8141fce
Christian Brabandt <cb@256bit.org>
parents:
7961
diff
changeset
|
1333 #if defined(MSWIN) |
7 | 1334 if (STRNCMP(b0p->b0_hname, "PC ", 3) == 0) |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1335 msg_puts_attr(_(" cannot be used with this version of Vim.\n"), |
7 | 1336 attr | MSG_HIST); |
1337 else | |
1338 #endif | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1339 msg_puts_attr(_(" cannot be used on this computer.\n"), |
7 | 1340 attr | MSG_HIST); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1341 msg_puts_attr(_("The file was created on "), attr | MSG_HIST); |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1342 // avoid going past the end of a corrupted hostname |
7 | 1343 b0p->b0_fname[0] = NUL; |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1344 msg_puts_attr((char *)b0p->b0_hname, attr | MSG_HIST); |
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1345 msg_puts_attr(_(",\nor the file has been damaged."), attr | MSG_HIST); |
7 | 1346 msg_end(); |
1347 goto theend; | |
1348 } | |
1105 | 1349 |
2267 | 1350 #ifdef FEAT_CRYPT |
24768
7334bf933510
patch 8.2.2922: computing array length is done in various ways
Bram Moolenaar <Bram@vim.org>
parents:
24703
diff
changeset
|
1351 for (i = 0; i < (int)ARRAY_LENGTH(id1_codes); ++i) |
6122 | 1352 if (id1_codes[i] == b0p->b0_id[1]) |
1353 b0_cm = i; | |
1354 if (b0_cm > 0) | |
2267 | 1355 mch_memmove(mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN); |
6122 | 1356 crypt_set_cm_option(buf, b0_cm < 0 ? 0 : b0_cm); |
2267 | 1357 #else |
1358 if (b0p->b0_id[1] != BLOCK0_ID1) | |
1359 { | |
26962
85866e069c24
patch 8.2.4010: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26958
diff
changeset
|
1360 semsg(_(e_str_is_encrypted_and_this_version_of_vim_does_not_support_encryption), mfp->mf_fname); |
2267 | 1361 goto theend; |
1362 } | |
1363 #endif | |
1364 | |
7 | 1365 /* |
1366 * If we guessed the wrong page size, we have to recalculate the | |
1367 * highest block number in the file. | |
1368 */ | |
1369 if (mfp->mf_page_size != (unsigned)char_to_long(b0p->b0_page_size)) | |
1370 { | |
1105 | 1371 unsigned previous_page_size = mfp->mf_page_size; |
1372 | |
7 | 1373 mf_new_page_size(mfp, (unsigned)char_to_long(b0p->b0_page_size)); |
1105 | 1374 if (mfp->mf_page_size < previous_page_size) |
1375 { | |
1376 msg_start(); | |
1377 msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST); | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1378 msg_puts_attr(_(" has been damaged (page size is smaller than minimum value).\n"), |
1105 | 1379 attr | MSG_HIST); |
1380 msg_end(); | |
1381 goto theend; | |
1382 } | |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
1383 if ((size = vim_lseek(mfp->mf_fd, (off_T)0L, SEEK_END)) <= 0) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1384 mfp->mf_blocknr_max = 0; // no file or empty file |
7 | 1385 else |
1386 mfp->mf_blocknr_max = (blocknr_T)(size / mfp->mf_page_size); | |
1387 mfp->mf_infile_count = mfp->mf_blocknr_max; | |
1105 | 1388 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1389 // need to reallocate the memory used to store the data |
1105 | 1390 p = alloc(mfp->mf_page_size); |
1391 if (p == NULL) | |
1392 goto theend; | |
1393 mch_memmove(p, hp->bh_data, previous_page_size); | |
1394 vim_free(hp->bh_data); | |
1395 hp->bh_data = p; | |
1396 b0p = (ZERO_BL *)(hp->bh_data); | |
7 | 1397 } |
1398 | |
2267 | 1399 /* |
1400 * If .swp file name given directly, use name from swap file for buffer. | |
1401 */ | |
7 | 1402 if (directly) |
1403 { | |
1404 expand_env(b0p->b0_fname, NameBuff, MAXPATHL); | |
1405 if (setfname(curbuf, NameBuff, NULL, TRUE) == FAIL) | |
1406 goto theend; | |
1407 } | |
1408 | |
1409 home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL, TRUE); | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15361
diff
changeset
|
1410 smsg(_("Using swap file \"%s\""), NameBuff); |
7 | 1411 |
1412 if (buf_spname(curbuf) != NULL) | |
3839 | 1413 vim_strncpy(NameBuff, buf_spname(curbuf), MAXPATHL - 1); |
7 | 1414 else |
1415 home_replace(NULL, curbuf->b_ffname, NameBuff, MAXPATHL, TRUE); | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15361
diff
changeset
|
1416 smsg(_("Original file \"%s\""), NameBuff); |
7 | 1417 msg_putchar('\n'); |
1418 | |
2267 | 1419 /* |
1420 * check date of swap file and original file | |
1421 */ | |
7 | 1422 mtime = char_to_long(b0p->b0_mtime); |
1423 if (curbuf->b_ffname != NULL | |
1424 && mch_stat((char *)curbuf->b_ffname, &org_stat) != -1 | |
1425 && ((mch_stat((char *)mfp->mf_fname, &swp_stat) != -1 | |
1426 && org_stat.st_mtime > swp_stat.st_mtime) | |
1427 || org_stat.st_mtime != mtime)) | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
1428 emsg(_(e_warning_original_file_may_have_been_changed)); |
7 | 1429 out_flush(); |
39 | 1430 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1431 // Get the 'fileformat' and 'fileencoding' from block zero. |
39 | 1432 b0_ff = (b0p->b0_flags & B0_FF_MASK); |
1433 if (b0p->b0_flags & B0_HAS_FENC) | |
1434 { | |
2271
2b33a7678e7b
Fix compiler warnings for shadowed variables. Make 'conceal' a long instead
Bram Moolenaar <bram@vim.org>
parents:
2267
diff
changeset
|
1435 int fnsize = B0_FNAME_SIZE_NOCRYPT; |
2267 | 1436 |
1437 #ifdef FEAT_CRYPT | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1438 // Use the same size as in add_b0_fenc(). |
2267 | 1439 if (b0p->b0_id[1] != BLOCK0_ID1) |
2271
2b33a7678e7b
Fix compiler warnings for shadowed variables. Make 'conceal' a long instead
Bram Moolenaar <bram@vim.org>
parents:
2267
diff
changeset
|
1440 fnsize = B0_FNAME_SIZE_CRYPT; |
2267 | 1441 #endif |
2271
2b33a7678e7b
Fix compiler warnings for shadowed variables. Make 'conceal' a long instead
Bram Moolenaar <bram@vim.org>
parents:
2267
diff
changeset
|
1442 for (p = b0p->b0_fname + fnsize; p > b0p->b0_fname && p[-1] != NUL; --p) |
39 | 1443 ; |
20830
9064044fd4f6
patch 8.2.0967: unnecessary type casts for vim_strnsave()
Bram Moolenaar <Bram@vim.org>
parents:
20599
diff
changeset
|
1444 b0_fenc = vim_strnsave(p, b0p->b0_fname + fnsize - p); |
39 | 1445 } |
1446 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1447 mf_put(mfp, hp, FALSE, FALSE); // release block 0 |
7 | 1448 hp = NULL; |
1449 | |
1450 /* | |
1451 * Now that we are sure that the file is going to be recovered, clear the | |
1452 * contents of the current buffer. | |
1453 */ | |
1454 while (!(curbuf->b_ml.ml_flags & ML_EMPTY)) | |
20599
d571231175b4
patch 8.2.0853: ml_delete() often called with FALSE argument
Bram Moolenaar <Bram@vim.org>
parents:
20583
diff
changeset
|
1455 ml_delete((linenr_T)1); |
7 | 1456 |
1457 /* | |
1458 * Try reading the original file to obtain the values of 'fileformat', | |
1459 * 'fileencoding', etc. Ignore errors. The text itself is not used. | |
2267 | 1460 * When the file is encrypted the user is asked to enter the key. |
7 | 1461 */ |
1462 if (curbuf->b_ffname != NULL) | |
2162
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1463 orig_file_status = readfile(curbuf->b_ffname, NULL, (linenr_T)0, |
7 | 1464 (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW); |
1465 | |
2267 | 1466 #ifdef FEAT_CRYPT |
1467 if (b0_cm >= 0) | |
1468 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1469 // Need to ask the user for the crypt key. If this fails we continue |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1470 // without a key, will probably get garbage text. |
2267 | 1471 if (*curbuf->b_p_key != NUL) |
1472 { | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15361
diff
changeset
|
1473 smsg(_("Swap file is encrypted: \"%s\""), fname_used); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1474 msg_puts(_("\nIf you entered a new crypt key but did not write the text file,")); |
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1475 msg_puts(_("\nenter the new crypt key.")); |
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1476 msg_puts(_("\nIf you wrote the text file after changing the crypt key press enter")); |
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1477 msg_puts(_("\nto use the same key for text file and swap file")); |
2267 | 1478 } |
1479 else | |
15470
55ccc2d353bd
patch 8.1.0743: giving error messages is not flexible
Bram Moolenaar <Bram@vim.org>
parents:
15361
diff
changeset
|
1480 smsg(_(need_key_msg), fname_used); |
6122 | 1481 buf->b_p_key = crypt_get_key(FALSE, FALSE); |
2267 | 1482 if (buf->b_p_key == NULL) |
1483 buf->b_p_key = curbuf->b_p_key; | |
1484 else if (*buf->b_p_key == NUL) | |
1485 { | |
1486 vim_free(buf->b_p_key); | |
1487 buf->b_p_key = curbuf->b_p_key; | |
1488 } | |
1489 if (buf->b_p_key == NULL) | |
1490 buf->b_p_key = empty_option; | |
2165
733f0dc510c3
Undo changes that are meant for the Vim 7.3 branch.
Bram Moolenaar <bram@vim.org>
parents:
2162
diff
changeset
|
1491 } |
2267 | 1492 #endif |
7 | 1493 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1494 // Use the 'fileformat' and 'fileencoding' as stored in the swap file. |
39 | 1495 if (b0_ff != 0) |
1496 set_fileformat(b0_ff - 1, OPT_LOCAL); | |
1497 if (b0_fenc != NULL) | |
1498 { | |
28457
4dcccb2673fe
patch 8.2.4753: error from setting an option is silently ignored
Bram Moolenaar <Bram@vim.org>
parents:
28357
diff
changeset
|
1499 set_option_value_give_err((char_u *)"fenc", 0L, b0_fenc, OPT_LOCAL); |
39 | 1500 vim_free(b0_fenc); |
1501 } | |
16996
d5e1e09a829f
patch 8.1.1498: ":write" increments b:changedtick even though nothing changed
Bram Moolenaar <Bram@vim.org>
parents:
16825
diff
changeset
|
1502 unchanged(curbuf, TRUE, TRUE); |
39 | 1503 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1504 bnum = 1; // start with block 1 |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1505 page_count = 1; // which is 1 page |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1506 lnum = 0; // append after line 0 in curbuf |
7 | 1507 line_count = 0; |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1508 idx = 0; // start with first index in block 1 |
7 | 1509 error = 0; |
1510 buf->b_ml.ml_stack_top = 0; | |
1511 buf->b_ml.ml_stack = NULL; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1512 buf->b_ml.ml_stack_size = 0; // no stack yet |
7 | 1513 |
1514 if (curbuf->b_ffname == NULL) | |
1515 cannot_open = TRUE; | |
1516 else | |
1517 cannot_open = FALSE; | |
1518 | |
1519 serious_error = FALSE; | |
1520 for ( ; !got_int; line_breakcheck()) | |
1521 { | |
1522 if (hp != NULL) | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1523 mf_put(mfp, hp, FALSE, FALSE); // release previous block |
7 | 1524 |
1525 /* | |
1526 * get block | |
1527 */ | |
27426
41e0dcf38521
patch 8.2.4241: some type casts are redundant
Bram Moolenaar <Bram@vim.org>
parents:
27231
diff
changeset
|
1528 if ((hp = mf_get(mfp, bnum, page_count)) == NULL) |
7 | 1529 { |
1530 if (bnum == 1) | |
1531 { | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
1532 semsg(_(e_unable_to_read_block_one_from_str), mfp->mf_fname); |
7 | 1533 goto theend; |
1534 } | |
1535 ++error; | |
1536 ml_append(lnum++, (char_u *)_("???MANY LINES MISSING"), | |
1537 (colnr_T)0, TRUE); | |
1538 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1539 else // there is a block |
7 | 1540 { |
1541 pp = (PTR_BL *)(hp->bh_data); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1542 if (pp->pb_id == PTR_ID) // it is a pointer block |
7 | 1543 { |
32290
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
1544 int ptr_block_error = FALSE; |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
1545 if (pp->pb_count_max != PB_COUNT_MAX(mfp)) |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
1546 { |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
1547 ptr_block_error = TRUE; |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
1548 pp->pb_count_max = PB_COUNT_MAX(mfp); |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
1549 } |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
1550 if (pp->pb_count > pp->pb_count_max) |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
1551 { |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
1552 ptr_block_error = TRUE; |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
1553 pp->pb_count = pp->pb_count_max; |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
1554 } |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
1555 if (ptr_block_error) |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
1556 emsg(_(e_warning_pointer_block_corrupted)); |
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
1557 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1558 // check line count when using pointer block first time |
7 | 1559 if (idx == 0 && line_count != 0) |
1560 { | |
1561 for (i = 0; i < (int)pp->pb_count; ++i) | |
1562 line_count -= pp->pb_pointer[i].pe_line_count; | |
1563 if (line_count != 0) | |
1564 { | |
1565 ++error; | |
1566 ml_append(lnum++, (char_u *)_("???LINE COUNT WRONG"), | |
1567 (colnr_T)0, TRUE); | |
1568 } | |
1569 } | |
1570 | |
1571 if (pp->pb_count == 0) | |
1572 { | |
1573 ml_append(lnum++, (char_u *)_("???EMPTY BLOCK"), | |
1574 (colnr_T)0, TRUE); | |
1575 ++error; | |
1576 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1577 else if (idx < (int)pp->pb_count) // go a block deeper |
7 | 1578 { |
1579 if (pp->pb_pointer[idx].pe_bnum < 0) | |
1580 { | |
1581 /* | |
1582 * Data block with negative block number. | |
1583 * Try to read lines from the original file. | |
1584 * This is slow, but it works. | |
1585 */ | |
1586 if (!cannot_open) | |
1587 { | |
1588 line_count = pp->pb_pointer[idx].pe_line_count; | |
1589 if (readfile(curbuf->b_ffname, NULL, lnum, | |
1590 pp->pb_pointer[idx].pe_old_lnum - 1, | |
10575
01a5f64a7a20
patch 8.0.0177: BufEnter autocommand not fired for a directory
Christian Brabandt <cb@256bit.org>
parents:
10359
diff
changeset
|
1591 line_count, NULL, 0) != OK) |
7 | 1592 cannot_open = TRUE; |
1593 else | |
1594 lnum += line_count; | |
1595 } | |
1596 if (cannot_open) | |
1597 { | |
1598 ++error; | |
1599 ml_append(lnum++, (char_u *)_("???LINES MISSING"), | |
1600 (colnr_T)0, TRUE); | |
1601 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1602 ++idx; // get same block again for next index |
7 | 1603 continue; |
1604 } | |
1605 | |
1606 /* | |
1607 * going one block deeper in the tree | |
1608 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1609 if ((top = ml_add_stack(buf)) < 0) // new entry in stack |
7 | 1610 { |
1611 ++error; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1612 break; // out of memory |
7 | 1613 } |
1614 ip = &(buf->b_ml.ml_stack[top]); | |
1615 ip->ip_bnum = bnum; | |
1616 ip->ip_index = idx; | |
1617 | |
1618 bnum = pp->pb_pointer[idx].pe_bnum; | |
1619 line_count = pp->pb_pointer[idx].pe_line_count; | |
1620 page_count = pp->pb_pointer[idx].pe_page_count; | |
2885 | 1621 idx = 0; |
7 | 1622 continue; |
1623 } | |
1624 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1625 else // not a pointer block |
7 | 1626 { |
1627 dp = (DATA_BL *)(hp->bh_data); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1628 if (dp->db_id != DATA_ID) // block id wrong |
7 | 1629 { |
1630 if (bnum == 1) | |
1631 { | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
1632 semsg(_(e_block_one_id_wrong_str_not_swp_file), |
7 | 1633 mfp->mf_fname); |
1634 goto theend; | |
1635 } | |
1636 ++error; | |
1637 ml_append(lnum++, (char_u *)_("???BLOCK MISSING"), | |
1638 (colnr_T)0, TRUE); | |
1639 } | |
1640 else | |
1641 { | |
1642 /* | |
32325
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1643 * It is a data block. |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1644 * Append all the lines in this block. |
7 | 1645 */ |
1646 has_error = FALSE; | |
32325
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1647 |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1648 // Check the length of the block. |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1649 // If wrong, use the length given in the pointer block. |
7 | 1650 if (page_count * mfp->mf_page_size != dp->db_txt_end) |
1651 { | |
1652 ml_append(lnum++, (char_u *)_("??? from here until ???END lines may be messed up"), | |
1653 (colnr_T)0, TRUE); | |
1654 ++error; | |
1655 has_error = TRUE; | |
1656 dp->db_txt_end = page_count * mfp->mf_page_size; | |
1657 } | |
1658 | |
32325
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1659 // Make sure there is a NUL at the end of the block so we |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1660 // don't go over the end when copying text. |
7 | 1661 *((char_u *)dp + dp->db_txt_end - 1) = NUL; |
1662 | |
32325
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1663 // Check the number of lines in the block. |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1664 // If wrong, use the count in the data block. |
7 | 1665 if (line_count != dp->db_line_count) |
1666 { | |
1667 ml_append(lnum++, (char_u *)_("??? from here until ???END lines may have been inserted/deleted"), | |
1668 (colnr_T)0, TRUE); | |
1669 ++error; | |
1670 has_error = TRUE; | |
1671 } | |
1672 | |
32325
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1673 int did_questions = FALSE; |
7 | 1674 for (i = 0; i < dp->db_line_count; ++i) |
1675 { | |
32325
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1676 if ((char_u *)&(dp->db_index[i]) |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1677 >= (char_u *)dp + dp->db_txt_start) |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1678 { |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1679 // line count must be wrong |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1680 ++error; |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1681 ml_append(lnum++, |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1682 (char_u *)_("??? lines may be missing"), |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1683 (colnr_T)0, TRUE); |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1684 break; |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1685 } |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1686 |
7 | 1687 txt_start = (dp->db_index[i] & DB_INDEX_MASK); |
1978 | 1688 if (txt_start <= (int)HEADER_SIZE |
7 | 1689 || txt_start >= (int)dp->db_txt_end) |
1690 { | |
32325
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1691 ++error; |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1692 // avoid lots of lines with "???" |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1693 if (did_questions) |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1694 continue; |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1695 did_questions = TRUE; |
7 | 1696 p = (char_u *)"???"; |
1697 } | |
1698 else | |
32325
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1699 { |
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1700 did_questions = FALSE; |
7 | 1701 p = (char_u *)dp + txt_start; |
32325
aa90a1f1a523
patch 9.0.1494: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
32305
diff
changeset
|
1702 } |
7 | 1703 ml_append(lnum++, p, (colnr_T)0, TRUE); |
1704 } | |
1705 if (has_error) | |
1978 | 1706 ml_append(lnum++, (char_u *)_("???END"), |
1707 (colnr_T)0, TRUE); | |
7 | 1708 } |
1709 } | |
1710 } | |
1711 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1712 if (buf->b_ml.ml_stack_top == 0) // finished |
7 | 1713 break; |
1714 | |
1715 /* | |
1716 * go one block up in the tree | |
1717 */ | |
1718 ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]); | |
1719 bnum = ip->ip_bnum; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1720 idx = ip->ip_index + 1; // go to next index |
7 | 1721 page_count = 1; |
1722 } | |
1723 | |
1724 /* | |
2162
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1725 * Compare the buffer contents with the original file. When they differ |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1726 * set the 'modified' flag. |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1727 * Lines 1 - lnum are the new contents. |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1728 * Lines lnum + 1 to ml_line_count are the original contents. |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1729 * Line ml_line_count + 1 in the dummy empty line. |
7 | 1730 */ |
2162
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1731 if (orig_file_status != OK || curbuf->b_ml.ml_line_count != lnum * 2 + 1) |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1732 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1733 // Recovering an empty file results in two lines and the first line is |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1734 // empty. Don't set the modified flag then. |
2162
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1735 if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL)) |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1736 { |
16632
30de89c1d090
patch 8.1.1318: code for text changes is in a "misc" file
Bram Moolenaar <Bram@vim.org>
parents:
16621
diff
changeset
|
1737 changed_internal(); |
10952
835604f3c37a
patch 8.0.0365: might free a dict item that wasn't allocated
Christian Brabandt <cb@256bit.org>
parents:
10896
diff
changeset
|
1738 ++CHANGEDTICK(curbuf); |
2162
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1739 } |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1740 } |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1741 else |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1742 { |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1743 for (idx = 1; idx <= lnum; ++idx) |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1744 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1745 // Need to copy one line, fetching the other one may flush it. |
2162
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1746 p = vim_strsave(ml_get(idx)); |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1747 i = STRCMP(p, ml_get(idx + lnum)); |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1748 vim_free(p); |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1749 if (i != 0) |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1750 { |
16632
30de89c1d090
patch 8.1.1318: code for text changes is in a "misc" file
Bram Moolenaar <Bram@vim.org>
parents:
16621
diff
changeset
|
1751 changed_internal(); |
10952
835604f3c37a
patch 8.0.0365: might free a dict item that wasn't allocated
Christian Brabandt <cb@256bit.org>
parents:
10896
diff
changeset
|
1752 ++CHANGEDTICK(curbuf); |
2162
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1753 break; |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1754 } |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1755 } |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1756 } |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1757 |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1758 /* |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1759 * Delete the lines from the original file and the dummy line from the |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1760 * empty buffer. These will now be after the last line in the buffer. |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1761 */ |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1762 while (curbuf->b_ml.ml_line_count > lnum |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1763 && !(curbuf->b_ml.ml_flags & ML_EMPTY)) |
20599
d571231175b4
patch 8.2.0853: ml_delete() often called with FALSE argument
Bram Moolenaar <Bram@vim.org>
parents:
20583
diff
changeset
|
1764 ml_delete(curbuf->b_ml.ml_line_count); |
7 | 1765 curbuf->b_flags |= BF_RECOVERED; |
24856
a81b883576d6
patch 8.2.2966: ml_get errors after recovering a file
Bram Moolenaar <Bram@vim.org>
parents:
24768
diff
changeset
|
1766 check_cursor(); |
7 | 1767 |
1768 recoverymode = FALSE; | |
1769 if (got_int) | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
1770 emsg(_(e_recovery_interrupted)); |
7 | 1771 else if (error) |
1772 { | |
1773 ++no_wait_return; | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1774 msg(">>>>>>>>>>>>>"); |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
1775 emsg(_(e_errors_detected_while_recovering_look_for_lines_starting_with_questions)); |
7 | 1776 --no_wait_return; |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1777 msg(_("See \":help E312\" for more information.")); |
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1778 msg(">>>>>>>>>>>>>"); |
7 | 1779 } |
1780 else | |
1781 { | |
2162
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1782 if (curbuf->b_changed) |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1783 { |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1784 msg(_("Recovery completed. You should check if everything is OK.")); |
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1785 msg_puts(_("\n(You might want to write out this file under another name\n")); |
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1786 msg_puts(_("and run diff with the original file to check for changes)")); |
2162
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1787 } |
0527eb0f6918
After recovery check if the text changed. If it did mark the buffer as
Bram Moolenaar <bram@vim.org>
parents:
2145
diff
changeset
|
1788 else |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1789 msg(_("Recovery completed. Buffer contents equals file contents.")); |
22846
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
1790 msg_puts(_("\nYou may want to delete the .swp file now.")); |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
1791 #if defined(UNIX) || defined(MSWIN) |
24089
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
1792 if (swapfile_process_running(b0p, fname_used)) |
22846
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
1793 { |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
1794 // Warn there could be an active Vim on the same file, the user may |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
1795 // want to kill it. |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
1796 msg_puts(_("\nNote: process STILL RUNNING: ")); |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
1797 msg_outnum(char_to_long(b0p->b0_pid)); |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
1798 } |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
1799 #endif |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
1800 msg_puts("\n\n"); |
7 | 1801 cmdline_row = msg_row; |
1802 } | |
2267 | 1803 #ifdef FEAT_CRYPT |
1804 if (*buf->b_p_key != NUL && STRCMP(curbuf->b_p_key, buf->b_p_key) != 0) | |
1805 { | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1806 msg_puts(_("Using crypt key from swap file for the text file.\n")); |
28457
4dcccb2673fe
patch 8.2.4753: error from setting an option is silently ignored
Bram Moolenaar <Bram@vim.org>
parents:
28357
diff
changeset
|
1807 set_option_value_give_err((char_u *)"key", 0L, buf->b_p_key, OPT_LOCAL); |
2267 | 1808 } |
1809 #endif | |
29732
89e1d67814a9
patch 9.0.0206: redraw flags are not named specifically
Bram Moolenaar <Bram@vim.org>
parents:
29682
diff
changeset
|
1810 redraw_curbuf_later(UPD_NOT_VALID); |
7 | 1811 |
1812 theend: | |
2267 | 1813 vim_free(fname_used); |
7 | 1814 recoverymode = FALSE; |
1815 if (mfp != NULL) | |
1816 { | |
1817 if (hp != NULL) | |
1818 mf_put(mfp, hp, FALSE, FALSE); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1819 mf_close(mfp, FALSE); // will also vim_free(mfp->mf_fname) |
7 | 1820 } |
1053 | 1821 if (buf != NULL) |
1822 { | |
2267 | 1823 #ifdef FEAT_CRYPT |
1824 if (buf->b_p_key != curbuf->b_p_key) | |
1825 free_string_option(buf->b_p_key); | |
2407
6bc102a4bff8
Fix memory access to 'cryptmethod' during recovery. (Dominique Pelle)
Bram Moolenaar <bram@vim.org>
parents:
2394
diff
changeset
|
1826 free_string_option(buf->b_p_cm); |
2267 | 1827 #endif |
1053 | 1828 vim_free(buf->b_ml.ml_stack); |
1829 vim_free(buf); | |
1830 } | |
7 | 1831 if (serious_error && called_from_main) |
1832 ml_close(curbuf, TRUE); | |
1833 else | |
1834 { | |
1835 apply_autocmds(EVENT_BUFREADPOST, NULL, curbuf->b_fname, FALSE, curbuf); | |
1836 apply_autocmds(EVENT_BUFWINENTER, NULL, curbuf->b_fname, FALSE, curbuf); | |
1837 } | |
1838 } | |
1839 | |
1840 /* | |
1841 * Find the names of swap files in current directory and the directory given | |
1842 * with the 'directory' option. | |
1843 * | |
1844 * Used to: | |
1845 * - list the swap files for "vim -r" | |
1846 * - count the number of swap files when recovering | |
1847 * - list the swap files when recovering | |
31347
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
1848 * - list the swap files for swapfilelist() |
7 | 1849 * - find the name of the n'th swap file when recovering |
1850 */ | |
1851 int | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1852 recover_names( |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1853 char_u *fname, // base for swap file name |
31347
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
1854 int do_list, // when TRUE, list the swap file names |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
1855 list_T *ret_list UNUSED, // when not NULL add file names to it |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1856 int nr, // when non-zero, return nr'th swap file name |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1857 char_u **fname_out) // result when "nr" > 0 |
7 | 1858 { |
1859 int num_names; | |
1860 char_u *(names[6]); | |
1861 char_u *tail; | |
1862 char_u *p; | |
1863 int num_files; | |
1864 int file_count = 0; | |
1865 char_u **files; | |
1866 char_u *dirp; | |
1867 char_u *dir_name; | |
2175 | 1868 char_u *fname_res = NULL; |
2145
de0e7ca61893
updated for version 7.2.427
Bram Moolenaar <bram@zimbu.org>
parents:
2108
diff
changeset
|
1869 #ifdef HAVE_READLINK |
de0e7ca61893
updated for version 7.2.427
Bram Moolenaar <bram@zimbu.org>
parents:
2108
diff
changeset
|
1870 char_u fname_buf[MAXPATHL]; |
2175 | 1871 #endif |
1872 | |
1873 if (fname != NULL) | |
1874 { | |
1875 #ifdef HAVE_READLINK | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1876 // Expand symlink in the file name, because the swap file is created |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1877 // with the actual file instead of with the symlink. |
2267 | 1878 if (resolve_symlink(fname, fname_buf) == OK) |
1879 fname_res = fname_buf; | |
1880 else | |
2145
de0e7ca61893
updated for version 7.2.427
Bram Moolenaar <bram@zimbu.org>
parents:
2108
diff
changeset
|
1881 #endif |
2267 | 1882 fname_res = fname; |
2175 | 1883 } |
7 | 1884 |
31347
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
1885 if (do_list) |
7 | 1886 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1887 // use msg() to start the scrolling properly |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
1888 msg(_("Swap files found:")); |
7 | 1889 msg_putchar('\n'); |
1890 } | |
1891 | |
1892 /* | |
1893 * Do the loop for every directory in 'directory'. | |
1894 * First allocate some memory to put the directory name in. | |
1895 */ | |
16764
ef00b6bc186b
patch 8.1.1384: using "int" for alloc() often results in compiler warnings
Bram Moolenaar <Bram@vim.org>
parents:
16738
diff
changeset
|
1896 dir_name = alloc(STRLEN(p_dir) + 1); |
7 | 1897 dirp = p_dir; |
1898 while (dir_name != NULL && *dirp) | |
1899 { | |
1900 /* | |
1901 * Isolate a directory name from *dirp and put it in dir_name (we know | |
1902 * it is large enough, so use 31000 for length). | |
1903 * Advance dirp to next directory name. | |
1904 */ | |
1905 (void)copy_option_part(&dirp, dir_name, 31000, ","); | |
1906 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1907 if (dir_name[0] == '.' && dir_name[1] == NUL) // check current dir |
7 | 1908 { |
2267 | 1909 if (fname == NULL) |
7 | 1910 { |
1911 #ifdef VMS | |
1912 names[0] = vim_strsave((char_u *)"*_sw%"); | |
1913 #else | |
1914 names[0] = vim_strsave((char_u *)"*.sw?"); | |
1915 #endif | |
15868
7fad90423bd2
patch 8.1.0941: macros for MS-Windows are inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15636
diff
changeset
|
1916 #if defined(UNIX) || defined(MSWIN) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1917 // For Unix names starting with a dot are special. MS-Windows |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1918 // supports this too, on some file systems. |
7 | 1919 names[1] = vim_strsave((char_u *)".*.sw?"); |
1920 names[2] = vim_strsave((char_u *)".sw?"); | |
1921 num_names = 3; | |
1922 #else | |
1923 # ifdef VMS | |
1924 names[1] = vim_strsave((char_u *)".*_sw%"); | |
1925 num_names = 2; | |
1926 # else | |
1927 num_names = 1; | |
1928 # endif | |
1929 #endif | |
1930 } | |
1931 else | |
2145
de0e7ca61893
updated for version 7.2.427
Bram Moolenaar <bram@zimbu.org>
parents:
2108
diff
changeset
|
1932 num_names = recov_file_names(names, fname_res, TRUE); |
7 | 1933 } |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1934 else // check directory dir_name |
7 | 1935 { |
2267 | 1936 if (fname == NULL) |
7 | 1937 { |
1938 #ifdef VMS | |
1939 names[0] = concat_fnames(dir_name, (char_u *)"*_sw%", TRUE); | |
1940 #else | |
1941 names[0] = concat_fnames(dir_name, (char_u *)"*.sw?", TRUE); | |
1942 #endif | |
15868
7fad90423bd2
patch 8.1.0941: macros for MS-Windows are inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15636
diff
changeset
|
1943 #if defined(UNIX) || defined(MSWIN) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1944 // For Unix names starting with a dot are special. MS-Windows |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1945 // supports this too, on some file systems. |
7 | 1946 names[1] = concat_fnames(dir_name, (char_u *)".*.sw?", TRUE); |
1947 names[2] = concat_fnames(dir_name, (char_u *)".sw?", TRUE); | |
1948 num_names = 3; | |
1949 #else | |
1950 # ifdef VMS | |
1951 names[1] = concat_fnames(dir_name, (char_u *)".*_sw%", TRUE); | |
1952 num_names = 2; | |
1953 # else | |
1954 num_names = 1; | |
1955 # endif | |
1956 #endif | |
1957 } | |
1958 else | |
1959 { | |
15868
7fad90423bd2
patch 8.1.0941: macros for MS-Windows are inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15636
diff
changeset
|
1960 #if defined(UNIX) || defined(MSWIN) |
10996
2f041b367cd9
patch 8.0.0387: compiler warnings
Christian Brabandt <cb@256bit.org>
parents:
10952
diff
changeset
|
1961 int len = (int)STRLEN(dir_name); |
10896
d513b653f5d0
patch 8.0.0337: invalid memory access in :recover command
Christian Brabandt <cb@256bit.org>
parents:
10889
diff
changeset
|
1962 |
d513b653f5d0
patch 8.0.0337: invalid memory access in :recover command
Christian Brabandt <cb@256bit.org>
parents:
10889
diff
changeset
|
1963 p = dir_name + len; |
d513b653f5d0
patch 8.0.0337: invalid memory access in :recover command
Christian Brabandt <cb@256bit.org>
parents:
10889
diff
changeset
|
1964 if (after_pathsep(dir_name, p) && len > 1 && p[-1] == p[-2]) |
7 | 1965 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
1966 // Ends with '//', Use Full path for swap name |
2145
de0e7ca61893
updated for version 7.2.427
Bram Moolenaar <bram@zimbu.org>
parents:
2108
diff
changeset
|
1967 tail = make_percent_swname(dir_name, fname_res); |
7 | 1968 } |
1969 else | |
1970 #endif | |
1971 { | |
2145
de0e7ca61893
updated for version 7.2.427
Bram Moolenaar <bram@zimbu.org>
parents:
2108
diff
changeset
|
1972 tail = gettail(fname_res); |
7 | 1973 tail = concat_fnames(dir_name, tail, TRUE); |
1974 } | |
1975 if (tail == NULL) | |
1976 num_names = 0; | |
1977 else | |
1978 { | |
1979 num_names = recov_file_names(names, tail, FALSE); | |
1980 vim_free(tail); | |
1981 } | |
1982 } | |
1983 } | |
1984 | |
16684
1c2d9f67d98f
patch 8.1.1344: Coverity complains about possibly using a NULL pointer
Bram Moolenaar <Bram@vim.org>
parents:
16666
diff
changeset
|
1985 // check for out-of-memory |
31347
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
1986 for (int i = 0; i < num_names; ++i) |
7 | 1987 { |
1988 if (names[i] == NULL) | |
1989 { | |
1990 for (i = 0; i < num_names; ++i) | |
1991 vim_free(names[i]); | |
1992 num_names = 0; | |
1993 } | |
1994 } | |
1995 if (num_names == 0) | |
1996 num_files = 0; | |
1997 else if (expand_wildcards(num_names, names, &num_files, &files, | |
16738
b52ea9c5f1db
patch 8.1.1371: cannot recover from a swap file
Bram Moolenaar <Bram@vim.org>
parents:
16684
diff
changeset
|
1998 EW_NOTENV|EW_KEEPALL|EW_FILE|EW_SILENT) == FAIL) |
7 | 1999 num_files = 0; |
2000 | |
2001 /* | |
2002 * When no swap file found, wildcard expansion might have failed (e.g. | |
2003 * not able to execute the shell). | |
2004 * Try finding a swap file by simply adding ".swp" to the file name. | |
2005 */ | |
2267 | 2006 if (*dirp == NUL && file_count + num_files == 0 && fname != NULL) |
7 | 2007 { |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
2008 stat_T st; |
7 | 2009 char_u *swapname; |
2010 | |
2145
de0e7ca61893
updated for version 7.2.427
Bram Moolenaar <bram@zimbu.org>
parents:
2108
diff
changeset
|
2011 swapname = modname(fname_res, |
2823 | 2012 #if defined(VMS) |
2145
de0e7ca61893
updated for version 7.2.427
Bram Moolenaar <bram@zimbu.org>
parents:
2108
diff
changeset
|
2013 (char_u *)"_swp", FALSE |
7 | 2014 #else |
2145
de0e7ca61893
updated for version 7.2.427
Bram Moolenaar <bram@zimbu.org>
parents:
2108
diff
changeset
|
2015 (char_u *)".swp", TRUE |
7 | 2016 #endif |
2145
de0e7ca61893
updated for version 7.2.427
Bram Moolenaar <bram@zimbu.org>
parents:
2108
diff
changeset
|
2017 ); |
7 | 2018 if (swapname != NULL) |
2019 { | |
16825
ce04ebdf26b8
patch 8.1.1414: alloc() returning "char_u *" causes a lot of type casts
Bram Moolenaar <Bram@vim.org>
parents:
16786
diff
changeset
|
2020 if (mch_stat((char *)swapname, &st) != -1) // It exists! |
7 | 2021 { |
16825
ce04ebdf26b8
patch 8.1.1414: alloc() returning "char_u *" causes a lot of type casts
Bram Moolenaar <Bram@vim.org>
parents:
16786
diff
changeset
|
2022 files = ALLOC_ONE(char_u *); |
7 | 2023 if (files != NULL) |
2024 { | |
2025 files[0] = swapname; | |
2026 swapname = NULL; | |
2027 num_files = 1; | |
2028 } | |
2029 } | |
2030 vim_free(swapname); | |
2031 } | |
2032 } | |
2033 | |
2034 /* | |
31347
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2035 * Remove swapfile name of the current buffer, it must be ignored. |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2036 * But keep it for swapfilelist(). |
7 | 2037 */ |
2038 if (curbuf->b_ml.ml_mfp != NULL | |
31347
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2039 && (p = curbuf->b_ml.ml_mfp->mf_fname) != NULL |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2040 && ret_list == NULL) |
7 | 2041 { |
31347
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2042 for (int i = 0; i < num_files; ++i) |
16738
b52ea9c5f1db
patch 8.1.1371: cannot recover from a swap file
Bram Moolenaar <Bram@vim.org>
parents:
16684
diff
changeset
|
2043 // Do not expand wildcards, on windows would try to expand |
b52ea9c5f1db
patch 8.1.1371: cannot recover from a swap file
Bram Moolenaar <Bram@vim.org>
parents:
16684
diff
changeset
|
2044 // "%tmp%" in "%tmp%file". |
b52ea9c5f1db
patch 8.1.1371: cannot recover from a swap file
Bram Moolenaar <Bram@vim.org>
parents:
16684
diff
changeset
|
2045 if (fullpathcmp(p, files[i], TRUE, FALSE) & FPC_SAME) |
7 | 2046 { |
16738
b52ea9c5f1db
patch 8.1.1371: cannot recover from a swap file
Bram Moolenaar <Bram@vim.org>
parents:
16684
diff
changeset
|
2047 // Remove the name from files[i]. Move further entries |
b52ea9c5f1db
patch 8.1.1371: cannot recover from a swap file
Bram Moolenaar <Bram@vim.org>
parents:
16684
diff
changeset
|
2048 // down. When the array becomes empty free it here, since |
b52ea9c5f1db
patch 8.1.1371: cannot recover from a swap file
Bram Moolenaar <Bram@vim.org>
parents:
16684
diff
changeset
|
2049 // FreeWild() won't be called below. |
7 | 2050 vim_free(files[i]); |
1855 | 2051 if (--num_files == 0) |
2052 vim_free(files); | |
2053 else | |
2054 for ( ; i < num_files; ++i) | |
2055 files[i] = files[i + 1]; | |
7 | 2056 } |
2057 } | |
838 | 2058 if (nr > 0) |
7 | 2059 { |
2060 file_count += num_files; | |
2061 if (nr <= file_count) | |
2062 { | |
2267 | 2063 *fname_out = vim_strsave( |
2064 files[nr - 1 + num_files - file_count]); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2065 dirp = (char_u *)""; // stop searching |
7 | 2066 } |
2067 } | |
31347
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2068 else if (do_list) |
7 | 2069 { |
2070 if (dir_name[0] == '.' && dir_name[1] == NUL) | |
2071 { | |
2267 | 2072 if (fname == NULL) |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2073 msg_puts(_(" In current directory:\n")); |
7 | 2074 else |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2075 msg_puts(_(" Using specified name:\n")); |
7 | 2076 } |
2077 else | |
2078 { | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2079 msg_puts(_(" In directory ")); |
7 | 2080 msg_home_replace(dir_name); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2081 msg_puts(":\n"); |
7 | 2082 } |
2083 | |
2084 if (num_files) | |
2085 { | |
31347
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2086 for (int i = 0; i < num_files; ++i) |
7 | 2087 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2088 // print the swap file name |
7 | 2089 msg_outnum((long)++file_count); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2090 msg_puts(". "); |
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2091 msg_puts((char *)gettail(files[i])); |
7 | 2092 msg_putchar('\n'); |
2093 (void)swapfile_info(files[i]); | |
2094 } | |
2095 } | |
2096 else | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2097 msg_puts(_(" -- none --\n")); |
7 | 2098 out_flush(); |
2099 } | |
31347
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2100 #ifdef FEAT_EVAL |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2101 else if (ret_list != NULL) |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2102 { |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2103 for (int i = 0; i < num_files; ++i) |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2104 { |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2105 char_u *name = concat_fnames(dir_name, files[i], TRUE); |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2106 if (name != NULL) |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2107 { |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2108 list_append_string(ret_list, name, -1); |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2109 vim_free(name); |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2110 } |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2111 } |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2112 } |
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2113 #endif |
7 | 2114 else |
2115 file_count += num_files; | |
2116 | |
31347
56a2af8c0980
patch 9.0.1007: there is no way to get a list of swap file names
Bram Moolenaar <Bram@vim.org>
parents:
30005
diff
changeset
|
2117 for (int i = 0; i < num_names; ++i) |
7 | 2118 vim_free(names[i]); |
838 | 2119 if (num_files > 0) |
2120 FreeWild(num_files, files); | |
7 | 2121 } |
2122 vim_free(dir_name); | |
2123 return file_count; | |
2124 } | |
2125 | |
15868
7fad90423bd2
patch 8.1.0941: macros for MS-Windows are inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15636
diff
changeset
|
2126 #if defined(UNIX) || defined(MSWIN) || defined(PROTO) |
7 | 2127 /* |
14475
dddba3937532
patch 8.1.0251: using full path is not supported for 'backupdir'
Christian Brabandt <cb@256bit.org>
parents:
14011
diff
changeset
|
2128 * Need _very_ long file names. |
7 | 2129 * Append the full path to name with path separators made into percent |
26018
c2d4e40a32a6
patch 8.2.3543: swapname has double slash when 'directory' ends in it
Bram Moolenaar <Bram@vim.org>
parents:
25953
diff
changeset
|
2130 * signs, to "dir". An unnamed buffer is handled as "" (<currentdir>/"") |
c2d4e40a32a6
patch 8.2.3543: swapname has double slash when 'directory' ends in it
Bram Moolenaar <Bram@vim.org>
parents:
25953
diff
changeset
|
2131 * The last character in "dir" must be an extra slash or backslash, it is |
c2d4e40a32a6
patch 8.2.3543: swapname has double slash when 'directory' ends in it
Bram Moolenaar <Bram@vim.org>
parents:
25953
diff
changeset
|
2132 * removed. |
7 | 2133 */ |
14475
dddba3937532
patch 8.1.0251: using full path is not supported for 'backupdir'
Christian Brabandt <cb@256bit.org>
parents:
14011
diff
changeset
|
2134 char_u * |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2135 make_percent_swname(char_u *dir, char_u *name) |
7 | 2136 { |
14475
dddba3937532
patch 8.1.0251: using full path is not supported for 'backupdir'
Christian Brabandt <cb@256bit.org>
parents:
14011
diff
changeset
|
2137 char_u *d = NULL, *s, *f; |
dddba3937532
patch 8.1.0251: using full path is not supported for 'backupdir'
Christian Brabandt <cb@256bit.org>
parents:
14011
diff
changeset
|
2138 |
dddba3937532
patch 8.1.0251: using full path is not supported for 'backupdir'
Christian Brabandt <cb@256bit.org>
parents:
14011
diff
changeset
|
2139 f = fix_fname(name != NULL ? name : (char_u *)""); |
31728
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
2140 if (f == NULL) |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
2141 return NULL; |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
2142 |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
2143 s = alloc(STRLEN(f) + 1); |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
2144 if (s != NULL) |
7 | 2145 { |
31728
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
2146 STRCPY(s, f); |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
2147 for (d = s; *d != NUL; MB_PTR_ADV(d)) |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
2148 if (vim_ispathsep(*d)) |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
2149 *d = '%'; |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
2150 |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
2151 dir[STRLEN(dir) - 1] = NUL; // remove one trailing slash |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
2152 d = concat_fnames(dir, s, TRUE); |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
2153 vim_free(s); |
7 | 2154 } |
31728
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
2155 vim_free(f); |
7 | 2156 return d; |
2157 } | |
2158 #endif | |
2159 | |
16455
1ae13586edf8
patch 8.1.1232: can't build on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
16453
diff
changeset
|
2160 #if (defined(UNIX) || defined(VMS) || defined(MSWIN)) \ |
1ae13586edf8
patch 8.1.1232: can't build on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
16453
diff
changeset
|
2161 && (defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)) |
1ae13586edf8
patch 8.1.1232: can't build on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
16453
diff
changeset
|
2162 # define HAVE_PROCESS_STILL_RUNNING |
7 | 2163 static int process_still_running; |
2164 #endif | |
2165 | |
14601
d0ff19a55579
patch 8.1.0314: build failure without the +eval feature
Christian Brabandt <cb@256bit.org>
parents:
14599
diff
changeset
|
2166 #if defined(FEAT_EVAL) || defined(PROTO) |
7 | 2167 /* |
14599
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2168 * Return information found in swapfile "fname" in dictionary "d". |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2169 * This is used by the swapinfo() function. |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2170 */ |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2171 void |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2172 get_b0_dict(char_u *fname, dict_T *d) |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2173 { |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2174 int fd; |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2175 struct block0 b0; |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2176 |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2177 if ((fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) >= 0) |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2178 { |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2179 if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2180 { |
14601
d0ff19a55579
patch 8.1.0314: build failure without the +eval feature
Christian Brabandt <cb@256bit.org>
parents:
14599
diff
changeset
|
2181 if (ml_check_b0_id(&b0) == FAIL) |
15267
762fccd84b7c
patch 8.1.0642: swapinfo() leaks memory
Bram Moolenaar <Bram@vim.org>
parents:
15255
diff
changeset
|
2182 dict_add_string(d, "error", (char_u *)"Not a swap file"); |
14601
d0ff19a55579
patch 8.1.0314: build failure without the +eval feature
Christian Brabandt <cb@256bit.org>
parents:
14599
diff
changeset
|
2183 else if (b0_magic_wrong(&b0)) |
15267
762fccd84b7c
patch 8.1.0642: swapinfo() leaks memory
Bram Moolenaar <Bram@vim.org>
parents:
15255
diff
changeset
|
2184 dict_add_string(d, "error", (char_u *)"Magic number mismatch"); |
14599
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2185 else |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2186 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2187 // we have swap information |
15267
762fccd84b7c
patch 8.1.0642: swapinfo() leaks memory
Bram Moolenaar <Bram@vim.org>
parents:
15255
diff
changeset
|
2188 dict_add_string_len(d, "version", b0.b0_version, 10); |
762fccd84b7c
patch 8.1.0642: swapinfo() leaks memory
Bram Moolenaar <Bram@vim.org>
parents:
15255
diff
changeset
|
2189 dict_add_string_len(d, "user", b0.b0_uname, B0_UNAME_SIZE); |
762fccd84b7c
patch 8.1.0642: swapinfo() leaks memory
Bram Moolenaar <Bram@vim.org>
parents:
15255
diff
changeset
|
2190 dict_add_string_len(d, "host", b0.b0_hname, B0_HNAME_SIZE); |
762fccd84b7c
patch 8.1.0642: swapinfo() leaks memory
Bram Moolenaar <Bram@vim.org>
parents:
15255
diff
changeset
|
2191 dict_add_string_len(d, "fname", b0.b0_fname, B0_FNAME_SIZE_ORG); |
14599
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2192 |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2193 dict_add_number(d, "pid", char_to_long(b0.b0_pid)); |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2194 dict_add_number(d, "mtime", char_to_long(b0.b0_mtime)); |
14601
d0ff19a55579
patch 8.1.0314: build failure without the +eval feature
Christian Brabandt <cb@256bit.org>
parents:
14599
diff
changeset
|
2195 dict_add_number(d, "dirty", b0.b0_dirty ? 1 : 0); |
d0ff19a55579
patch 8.1.0314: build failure without the +eval feature
Christian Brabandt <cb@256bit.org>
parents:
14599
diff
changeset
|
2196 # ifdef CHECK_INODE |
14599
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2197 dict_add_number(d, "inode", char_to_long(b0.b0_ino)); |
14601
d0ff19a55579
patch 8.1.0314: build failure without the +eval feature
Christian Brabandt <cb@256bit.org>
parents:
14599
diff
changeset
|
2198 # endif |
14599
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2199 } |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2200 } |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2201 else |
15267
762fccd84b7c
patch 8.1.0642: swapinfo() leaks memory
Bram Moolenaar <Bram@vim.org>
parents:
15255
diff
changeset
|
2202 dict_add_string(d, "error", (char_u *)"Cannot read file"); |
14599
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2203 close(fd); |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2204 } |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2205 else |
15267
762fccd84b7c
patch 8.1.0642: swapinfo() leaks memory
Bram Moolenaar <Bram@vim.org>
parents:
15255
diff
changeset
|
2206 dict_add_string(d, "error", (char_u *)"Cannot open file"); |
14599
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2207 } |
14601
d0ff19a55579
patch 8.1.0314: build failure without the +eval feature
Christian Brabandt <cb@256bit.org>
parents:
14599
diff
changeset
|
2208 #endif |
14599
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2209 |
72d6f6f7ead7
patch 8.1.0313: information about a swap file is unavailable
Christian Brabandt <cb@256bit.org>
parents:
14593
diff
changeset
|
2210 /* |
580 | 2211 * Give information about an existing swap file. |
7 | 2212 * Returns timestamp (0 when unknown). |
2213 */ | |
2214 static time_t | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2215 swapfile_info(char_u *fname) |
7 | 2216 { |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
2217 stat_T st; |
7 | 2218 int fd; |
2219 struct block0 b0; | |
2220 #ifdef UNIX | |
2221 char_u uname[B0_UNAME_SIZE]; | |
2222 #endif | |
2223 | |
16621
7ad3fc329e08
patch 8.1.1313: warnings for using localtime() and ctime()
Bram Moolenaar <Bram@vim.org>
parents:
16455
diff
changeset
|
2224 // print the swap file date |
7 | 2225 if (mch_stat((char *)fname, &st) != -1) |
2226 { | |
2227 #ifdef UNIX | |
16621
7ad3fc329e08
patch 8.1.1313: warnings for using localtime() and ctime()
Bram Moolenaar <Bram@vim.org>
parents:
16455
diff
changeset
|
2228 // print name of owner of the file |
7 | 2229 if (mch_get_uname(st.st_uid, uname, B0_UNAME_SIZE) == OK) |
2230 { | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2231 msg_puts(_(" owned by: ")); |
7 | 2232 msg_outtrans(uname); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2233 msg_puts(_(" dated: ")); |
7 | 2234 } |
2235 else | |
2236 #endif | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2237 msg_puts(_(" dated: ")); |
16621
7ad3fc329e08
patch 8.1.1313: warnings for using localtime() and ctime()
Bram Moolenaar <Bram@vim.org>
parents:
16455
diff
changeset
|
2238 msg_puts(get_ctime(st.st_mtime, TRUE)); |
7 | 2239 } |
16621
7ad3fc329e08
patch 8.1.1313: warnings for using localtime() and ctime()
Bram Moolenaar <Bram@vim.org>
parents:
16455
diff
changeset
|
2240 else |
7ad3fc329e08
patch 8.1.1313: warnings for using localtime() and ctime()
Bram Moolenaar <Bram@vim.org>
parents:
16455
diff
changeset
|
2241 st.st_mtime = 0; |
7 | 2242 |
2243 /* | |
2244 * print the original file name | |
2245 */ | |
2246 fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0); | |
2247 if (fd >= 0) | |
2248 { | |
2664 | 2249 if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) |
7 | 2250 { |
2251 if (STRNCMP(b0.b0_version, "VIM 3.0", 7) == 0) | |
2252 { | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2253 msg_puts(_(" [from Vim version 3.0]")); |
7 | 2254 } |
2267 | 2255 else if (ml_check_b0_id(&b0) == FAIL) |
7 | 2256 { |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2257 msg_puts(_(" [does not look like a Vim swap file]")); |
7 | 2258 } |
2259 else | |
2260 { | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2261 msg_puts(_(" file name: ")); |
7 | 2262 if (b0.b0_fname[0] == NUL) |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2263 msg_puts(_("[No Name]")); |
7 | 2264 else |
2265 msg_outtrans(b0.b0_fname); | |
2266 | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2267 msg_puts(_("\n modified: ")); |
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2268 msg_puts(b0.b0_dirty ? _("YES") : _("no")); |
7 | 2269 |
2270 if (*(b0.b0_uname) != NUL) | |
2271 { | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2272 msg_puts(_("\n user name: ")); |
7 | 2273 msg_outtrans(b0.b0_uname); |
2274 } | |
2275 | |
2276 if (*(b0.b0_hname) != NUL) | |
2277 { | |
2278 if (*(b0.b0_uname) != NUL) | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2279 msg_puts(_(" host name: ")); |
7 | 2280 else |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2281 msg_puts(_("\n host name: ")); |
7 | 2282 msg_outtrans(b0.b0_hname); |
2283 } | |
2284 | |
2285 if (char_to_long(b0.b0_pid) != 0L) | |
2286 { | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2287 msg_puts(_("\n process ID: ")); |
7 | 2288 msg_outnum(char_to_long(b0.b0_pid)); |
16453
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2289 #if defined(UNIX) || defined(MSWIN) |
24089
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
2290 if (swapfile_process_running(&b0, fname)) |
7 | 2291 { |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2292 msg_puts(_(" (STILL RUNNING)")); |
16455
1ae13586edf8
patch 8.1.1232: can't build on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
16453
diff
changeset
|
2293 # ifdef HAVE_PROCESS_STILL_RUNNING |
7 | 2294 process_still_running = TRUE; |
2295 # endif | |
2296 } | |
2297 #endif | |
2298 } | |
2299 | |
2300 if (b0_magic_wrong(&b0)) | |
2301 { | |
8212
05b88224cea1
commit https://github.com/vim/vim/commit/48e330aff911be1c798c88a973af6437a8141fce
Christian Brabandt <cb@256bit.org>
parents:
7961
diff
changeset
|
2302 #if defined(MSWIN) |
7 | 2303 if (STRNCMP(b0.b0_hname, "PC ", 3) == 0) |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2304 msg_puts(_("\n [not usable with this version of Vim]")); |
7 | 2305 else |
2306 #endif | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2307 msg_puts(_("\n [not usable on this computer]")); |
7 | 2308 } |
2309 } | |
2310 } | |
2311 else | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2312 msg_puts(_(" [cannot be read]")); |
7 | 2313 close(fd); |
2314 } | |
2315 else | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2316 msg_puts(_(" [cannot be opened]")); |
7 | 2317 msg_putchar('\n'); |
2318 | |
16621
7ad3fc329e08
patch 8.1.1313: warnings for using localtime() and ctime()
Bram Moolenaar <Bram@vim.org>
parents:
16455
diff
changeset
|
2319 return st.st_mtime; |
7 | 2320 } |
2321 | |
16453
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2322 /* |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2323 * Return TRUE if the swap file looks OK and there are no changes, thus it can |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2324 * be safely deleted. |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2325 */ |
28175
3cc909ea91a8
patch 8.2.4613: return type of swapfile_unchanged() is wrong
Bram Moolenaar <Bram@vim.org>
parents:
27752
diff
changeset
|
2326 static int |
16453
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2327 swapfile_unchanged(char_u *fname) |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2328 { |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2329 stat_T st; |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2330 int fd; |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2331 struct block0 b0; |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2332 int ret = TRUE; |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2333 |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2334 // must be able to stat the swap file |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2335 if (mch_stat((char *)fname, &st) == -1) |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2336 return FALSE; |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2337 |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2338 // must be able to read the first block |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2339 fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0); |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2340 if (fd < 0) |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2341 return FALSE; |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2342 if (read_eintr(fd, &b0, sizeof(b0)) != sizeof(b0)) |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2343 { |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2344 close(fd); |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2345 return FALSE; |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2346 } |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2347 |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2348 // the ID and magic number must be correct |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2349 if (ml_check_b0_id(&b0) == FAIL|| b0_magic_wrong(&b0)) |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2350 ret = FALSE; |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2351 |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2352 // must be unchanged |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2353 if (b0.b0_dirty) |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2354 ret = FALSE; |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2355 |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2356 #if defined(UNIX) || defined(MSWIN) |
22846
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2357 // Host name must be known and must equal the current host name, otherwise |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2358 // comparing pid is meaningless. |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2359 if (*(b0.b0_hname) == NUL) |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2360 { |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2361 ret = FALSE; |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2362 } |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2363 else |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2364 { |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2365 char_u hostname[B0_HNAME_SIZE]; |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2366 |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2367 mch_get_host_name(hostname, B0_HNAME_SIZE); |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2368 hostname[B0_HNAME_SIZE - 1] = NUL; |
22959
4cce4a5d3fd3
patch 8.2.2026: Coverity warns for possibly using not NUL terminated string
Bram Moolenaar <Bram@vim.org>
parents:
22846
diff
changeset
|
2369 b0.b0_hname[B0_HNAME_SIZE - 1] = NUL; // in case of corruption |
22846
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2370 if (STRICMP(b0.b0_hname, hostname) != 0) |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2371 ret = FALSE; |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2372 } |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2373 |
18498
9e6d5a4abb1c
patch 8.1.2243: typos in comments
Bram Moolenaar <Bram@vim.org>
parents:
18459
diff
changeset
|
2374 // process must be known and not be running |
24089
cdeec1389c8c
patch 8.2.2586: process id may be invalid
Bram Moolenaar <Bram@vim.org>
parents:
23776
diff
changeset
|
2375 if (char_to_long(b0.b0_pid) == 0L || swapfile_process_running(&b0, fname)) |
16453
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2376 ret = FALSE; |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2377 #endif |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2378 |
22846
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2379 // We do not check the user, it should be irrelevant for whether the swap |
83c2c489cb1b
patch 8.2.1970: it is easy to make mistakes when cleaning up swap files
Bram Moolenaar <Bram@vim.org>
parents:
22699
diff
changeset
|
2380 // file is still useful. |
16453
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2381 |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2382 close(fd); |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2383 return ret; |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2384 } |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
2385 |
7 | 2386 static int |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2387 recov_file_names(char_u **names, char_u *path, int prepend_dot) |
7 | 2388 { |
2389 int num_names; | |
2390 | |
2391 /* | |
2392 * (Win32 and Win64) never short names, but do prepend a dot. | |
2393 * (Not MS-DOS or Win32 or Win64) maybe short name, maybe not: Try both. | |
2394 * Only use the short name if it is different. | |
2395 */ | |
2396 char_u *p; | |
2397 int i; | |
15868
7fad90423bd2
patch 8.1.0941: macros for MS-Windows are inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15636
diff
changeset
|
2398 # ifndef MSWIN |
7 | 2399 int shortname = curbuf->b_shortname; |
2400 | |
2401 curbuf->b_shortname = FALSE; | |
2402 # endif | |
2403 | |
2404 num_names = 0; | |
2405 | |
2406 /* | |
2407 * May also add the file name with a dot prepended, for swap file in same | |
2408 * dir as original file. | |
2409 */ | |
2410 if (prepend_dot) | |
2411 { | |
2412 names[num_names] = modname(path, (char_u *)".sw?", TRUE); | |
2413 if (names[num_names] == NULL) | |
2414 goto end; | |
2415 ++num_names; | |
2416 } | |
2417 | |
2418 /* | |
2419 * Form the normal swap file name pattern by appending ".sw?". | |
2420 */ | |
2421 #ifdef VMS | |
2422 names[num_names] = concat_fnames(path, (char_u *)"_sw%", FALSE); | |
2423 #else | |
2424 names[num_names] = concat_fnames(path, (char_u *)".sw?", FALSE); | |
2425 #endif | |
2426 if (names[num_names] == NULL) | |
2427 goto end; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2428 if (num_names >= 1) // check if we have the same name twice |
7 | 2429 { |
2430 p = names[num_names - 1]; | |
2431 i = (int)STRLEN(names[num_names - 1]) - (int)STRLEN(names[num_names]); | |
2432 if (i > 0) | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2433 p += i; // file name has been expanded to full path |
7 | 2434 |
2435 if (STRCMP(p, names[num_names]) != 0) | |
2436 ++num_names; | |
2437 else | |
2438 vim_free(names[num_names]); | |
2439 } | |
2440 else | |
2441 ++num_names; | |
2442 | |
15868
7fad90423bd2
patch 8.1.0941: macros for MS-Windows are inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15636
diff
changeset
|
2443 # ifndef MSWIN |
7 | 2444 /* |
2445 * Also try with 'shortname' set, in case the file is on a DOS filesystem. | |
2446 */ | |
2447 curbuf->b_shortname = TRUE; | |
2448 #ifdef VMS | |
2449 names[num_names] = modname(path, (char_u *)"_sw%", FALSE); | |
2450 #else | |
2451 names[num_names] = modname(path, (char_u *)".sw?", FALSE); | |
2452 #endif | |
2453 if (names[num_names] == NULL) | |
2454 goto end; | |
2455 | |
2456 /* | |
2457 * Remove the one from 'shortname', if it's the same as with 'noshortname'. | |
2458 */ | |
2459 p = names[num_names]; | |
2460 i = STRLEN(names[num_names]) - STRLEN(names[num_names - 1]); | |
2461 if (i > 0) | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2462 p += i; // file name has been expanded to full path |
7 | 2463 if (STRCMP(names[num_names - 1], p) == 0) |
2464 vim_free(names[num_names]); | |
2465 else | |
2466 ++num_names; | |
2467 # endif | |
2468 | |
2469 end: | |
15868
7fad90423bd2
patch 8.1.0941: macros for MS-Windows are inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15636
diff
changeset
|
2470 # ifndef MSWIN |
7 | 2471 curbuf->b_shortname = shortname; |
2472 # endif | |
2473 | |
2474 return num_names; | |
2475 } | |
2476 | |
2477 /* | |
2478 * sync all memlines | |
2479 * | |
2480 * If 'check_file' is TRUE, check if original file exists and was not changed. | |
2481 * If 'check_char' is TRUE, stop syncing when character becomes available, but | |
2482 * always sync at least one block. | |
2483 */ | |
2484 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2485 ml_sync_all(int check_file, int check_char) |
7 | 2486 { |
2487 buf_T *buf; | |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
2488 stat_T st; |
7 | 2489 |
9649
fd9727ae3c49
commit https://github.com/vim/vim/commit/2932359000b2f918d5fade79ea4d124d5943cd07
Christian Brabandt <cb@256bit.org>
parents:
9536
diff
changeset
|
2490 FOR_ALL_BUFFERS(buf) |
7 | 2491 { |
24970
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
2492 if (buf->b_ml.ml_mfp == NULL |
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
2493 || buf->b_ml.ml_mfp->mf_fname == NULL |
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
2494 || buf->b_ml.ml_mfp->mf_fd < 0) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2495 continue; // no file |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2496 |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2497 ml_flush_line(buf); // flush buffered line |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2498 // flush locked block |
7 | 2499 (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); |
2500 if (bufIsChanged(buf) && check_file && mf_need_trans(buf->b_ml.ml_mfp) | |
2501 && buf->b_ffname != NULL) | |
2502 { | |
2503 /* | |
2504 * If the original file does not exist anymore or has been changed | |
2505 * call ml_preserve() to get rid of all negative numbered blocks. | |
2506 */ | |
2507 if (mch_stat((char *)buf->b_ffname, &st) == -1 | |
2508 || st.st_mtime != buf->b_mtime_read | |
25953
d7e1cf30728c
patch 8.2.3510: changes are only detected with one second accuracy
Bram Moolenaar <Bram@vim.org>
parents:
25913
diff
changeset
|
2509 #ifdef ST_MTIM_NSEC |
d7e1cf30728c
patch 8.2.3510: changes are only detected with one second accuracy
Bram Moolenaar <Bram@vim.org>
parents:
25913
diff
changeset
|
2510 || st.ST_MTIM_NSEC != buf->b_mtime_read_ns |
d7e1cf30728c
patch 8.2.3510: changes are only detected with one second accuracy
Bram Moolenaar <Bram@vim.org>
parents:
25913
diff
changeset
|
2511 #endif |
2241
60da25e3aab7
Correct use of long instead of off_t for file size. (James Vega)
Bram Moolenaar <bram@vim.org>
parents:
2240
diff
changeset
|
2512 || st.st_size != buf->b_orig_size) |
7 | 2513 { |
2514 ml_preserve(buf, FALSE); | |
2515 did_check_timestamps = FALSE; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2516 need_check_timestamps = TRUE; // give message later |
7 | 2517 } |
2518 } | |
32503
5d07e7e9580f
patch 9.0.1583: get E304 when using 'cryptmethod' "xchacha20v2"
Bram Moolenaar <Bram@vim.org>
parents:
32325
diff
changeset
|
2519 if (buf->b_ml.ml_mfp->mf_dirty == MF_DIRTY_YES) |
7 | 2520 { |
2521 (void)mf_sync(buf->b_ml.ml_mfp, (check_char ? MFS_STOP : 0) | |
2522 | (bufIsChanged(buf) ? MFS_FLUSH : 0)); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2523 if (check_char && ui_char_avail()) // character available now |
7 | 2524 break; |
2525 } | |
2526 } | |
2527 } | |
2528 | |
2529 /* | |
2530 * sync one buffer, including negative blocks | |
2531 * | |
2532 * after this all the blocks are in the swap file | |
2533 * | |
2534 * Used for the :preserve command and when the original file has been | |
2535 * changed or deleted. | |
2536 * | |
2537 * when message is TRUE the success of preserving is reported | |
2538 */ | |
2539 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2540 ml_preserve(buf_T *buf, int message) |
7 | 2541 { |
2542 bhdr_T *hp; | |
2543 linenr_T lnum; | |
2544 memfile_T *mfp = buf->b_ml.ml_mfp; | |
2545 int status; | |
2546 int got_int_save = got_int; | |
2547 | |
2548 if (mfp == NULL || mfp->mf_fname == NULL) | |
2549 { | |
2550 if (message) | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
2551 emsg(_(e_cannot_preserve_there_is_no_swap_file)); |
7 | 2552 return; |
2553 } | |
2554 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2555 // We only want to stop when interrupted here, not when interrupted |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2556 // before. |
7 | 2557 got_int = FALSE; |
2558 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2559 ml_flush_line(buf); // flush buffered line |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2560 (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); // flush locked block |
7 | 2561 status = mf_sync(mfp, MFS_ALL | MFS_FLUSH); |
2562 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2563 // stack is invalid after mf_sync(.., MFS_ALL) |
7 | 2564 buf->b_ml.ml_stack_top = 0; |
2565 | |
2566 /* | |
2567 * Some of the data blocks may have been changed from negative to | |
2568 * positive block number. In that case the pointer blocks need to be | |
2569 * updated. | |
2570 * | |
2571 * We don't know in which pointer block the references are, so we visit | |
2572 * all data blocks until there are no more translations to be done (or | |
2573 * we hit the end of the file, which can only happen in case a write fails, | |
2574 * e.g. when file system if full). | |
2575 * ml_find_line() does the work by translating the negative block numbers | |
2576 * when getting the first line of each data block. | |
2577 */ | |
2578 if (mf_need_trans(mfp) && !got_int) | |
2579 { | |
2580 lnum = 1; | |
2581 while (mf_need_trans(mfp) && lnum <= buf->b_ml.ml_line_count) | |
2582 { | |
2583 hp = ml_find_line(buf, lnum, ML_FIND); | |
2584 if (hp == NULL) | |
2585 { | |
2586 status = FAIL; | |
2587 goto theend; | |
2588 } | |
2589 CHECK(buf->b_ml.ml_locked_low != lnum, "low != lnum"); | |
2590 lnum = buf->b_ml.ml_locked_high + 1; | |
2591 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2592 (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); // flush locked block |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2593 // sync the updated pointer blocks |
7 | 2594 if (mf_sync(mfp, MFS_ALL | MFS_FLUSH) == FAIL) |
2595 status = FAIL; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2596 buf->b_ml.ml_stack_top = 0; // stack is invalid now |
7 | 2597 } |
2598 theend: | |
2599 got_int |= got_int_save; | |
2600 | |
2601 if (message) | |
2602 { | |
2603 if (status == OK) | |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
2604 msg(_("File preserved")); |
7 | 2605 else |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
2606 emsg(_(e_preserve_failed)); |
7 | 2607 } |
2608 } | |
2609 | |
2610 /* | |
2611 * NOTE: The pointer returned by the ml_get_*() functions only remains valid | |
2612 * until the next call! | |
2613 * line1 = ml_get(1); | |
2614 * line2 = ml_get(2); // line1 is now invalid! | |
2615 * Make a copy of the line if necessary. | |
2616 */ | |
2617 /* | |
2657 | 2618 * Return a pointer to a (read-only copy of a) line. |
7 | 2619 * |
2620 * On failure an error message is given and IObuff is returned (to avoid | |
2621 * having to check for error everywhere). | |
2622 */ | |
2623 char_u * | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2624 ml_get(linenr_T lnum) |
7 | 2625 { |
2626 return ml_get_buf(curbuf, lnum, FALSE); | |
2627 } | |
2628 | |
2629 /* | |
2657 | 2630 * Return pointer to position "pos". |
7 | 2631 */ |
2632 char_u * | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2633 ml_get_pos(pos_T *pos) |
7 | 2634 { |
2635 return (ml_get_buf(curbuf, pos->lnum, FALSE) + pos->col); | |
2636 } | |
2637 | |
2638 /* | |
2657 | 2639 * Return pointer to cursor line. |
7 | 2640 */ |
2641 char_u * | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2642 ml_get_curline(void) |
7 | 2643 { |
2644 return ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE); | |
2645 } | |
2646 | |
2647 /* | |
2657 | 2648 * Return pointer to cursor position. |
7 | 2649 */ |
2650 char_u * | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2651 ml_get_cursor(void) |
7 | 2652 { |
2653 return (ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE) + | |
2654 curwin->w_cursor.col); | |
2655 } | |
2656 | |
2657 /* | |
2657 | 2658 * Return a pointer to a line in a specific buffer |
7 | 2659 * |
2660 * "will_change": if TRUE mark the buffer dirty (chars in the line will be | |
2661 * changed) | |
2662 */ | |
2663 char_u * | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2664 ml_get_buf( |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2665 buf_T *buf, |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2666 linenr_T lnum, |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2667 int will_change) // line will be changed |
7 | 2668 { |
1068 | 2669 bhdr_T *hp; |
2670 DATA_BL *dp; | |
2671 static int recursive = 0; | |
26286
2815b25993fb
patch 8.2.3674: when ml_get_buf() fails it messes up IObuff
Bram Moolenaar <Bram@vim.org>
parents:
26018
diff
changeset
|
2672 static char_u questions[4]; |
7 | 2673 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2674 if (lnum > buf->b_ml.ml_line_count) // invalid line number |
7 | 2675 { |
1068 | 2676 if (recursive == 0) |
2677 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2678 // Avoid giving this message for a recursive call, may happen when |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2679 // the GUI redraws part of the text. |
1068 | 2680 ++recursive; |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
2681 siemsg(_(e_ml_get_invalid_lnum_nr), lnum); |
1068 | 2682 --recursive; |
2683 } | |
27746
2d24aad37e60
patch 8.2.4399: crash after ml_get error
Bram Moolenaar <Bram@vim.org>
parents:
27453
diff
changeset
|
2684 ml_flush_line(buf); |
7 | 2685 errorret: |
26286
2815b25993fb
patch 8.2.3674: when ml_get_buf() fails it messes up IObuff
Bram Moolenaar <Bram@vim.org>
parents:
26018
diff
changeset
|
2686 STRCPY(questions, "???"); |
16786
98ca522e6453
patch 8.1.1395: saving for undo may access invalid memory
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2687 buf->b_ml.ml_line_len = 4; |
27746
2d24aad37e60
patch 8.2.4399: crash after ml_get error
Bram Moolenaar <Bram@vim.org>
parents:
27453
diff
changeset
|
2688 buf->b_ml.ml_line_lnum = lnum; |
26286
2815b25993fb
patch 8.2.3674: when ml_get_buf() fails it messes up IObuff
Bram Moolenaar <Bram@vim.org>
parents:
26018
diff
changeset
|
2689 return questions; |
7 | 2690 } |
16786
98ca522e6453
patch 8.1.1395: saving for undo may access invalid memory
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2691 if (lnum <= 0) // pretend line 0 is line 1 |
7 | 2692 lnum = 1; |
2693 | |
16786
98ca522e6453
patch 8.1.1395: saving for undo may access invalid memory
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2694 if (buf->b_ml.ml_mfp == NULL) // there are no lines |
98ca522e6453
patch 8.1.1395: saving for undo may access invalid memory
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2695 { |
98ca522e6453
patch 8.1.1395: saving for undo may access invalid memory
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2696 buf->b_ml.ml_line_len = 1; |
7 | 2697 return (char_u *)""; |
16786
98ca522e6453
patch 8.1.1395: saving for undo may access invalid memory
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2698 } |
7 | 2699 |
2108
3cdf2a653e00
updated for version 7.2.391
Bram Moolenaar <bram@zimbu.org>
parents:
2075
diff
changeset
|
2700 /* |
3cdf2a653e00
updated for version 7.2.391
Bram Moolenaar <bram@zimbu.org>
parents:
2075
diff
changeset
|
2701 * See if it is the same line as requested last time. |
3cdf2a653e00
updated for version 7.2.391
Bram Moolenaar <bram@zimbu.org>
parents:
2075
diff
changeset
|
2702 * Otherwise may need to flush last used line. |
3cdf2a653e00
updated for version 7.2.391
Bram Moolenaar <bram@zimbu.org>
parents:
2075
diff
changeset
|
2703 * Don't use the last used line when 'swapfile' is reset, need to load all |
3cdf2a653e00
updated for version 7.2.391
Bram Moolenaar <bram@zimbu.org>
parents:
2075
diff
changeset
|
2704 * blocks. |
3cdf2a653e00
updated for version 7.2.391
Bram Moolenaar <bram@zimbu.org>
parents:
2075
diff
changeset
|
2705 */ |
1066 | 2706 if (buf->b_ml.ml_line_lnum != lnum || mf_dont_release) |
7 | 2707 { |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2708 unsigned start, end; |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2709 colnr_T len; |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2710 int idx; |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2711 |
7 | 2712 ml_flush_line(buf); |
2713 | |
2714 /* | |
2715 * Find the data block containing the line. | |
2716 * This also fills the stack with the blocks from the root to the data | |
2717 * block and releases any locked block. | |
2718 */ | |
2719 if ((hp = ml_find_line(buf, lnum, ML_FIND)) == NULL) | |
2720 { | |
1068 | 2721 if (recursive == 0) |
2722 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2723 // Avoid giving this message for a recursive call, may happen |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2724 // when the GUI redraws part of the text. |
1068 | 2725 ++recursive; |
18459
5c0437acebb7
patch 8.1.2223: cannot see what buffer an ml_get error is for
Bram Moolenaar <Bram@vim.org>
parents:
18372
diff
changeset
|
2726 get_trans_bufname(buf); |
5c0437acebb7
patch 8.1.2223: cannot see what buffer an ml_get error is for
Bram Moolenaar <Bram@vim.org>
parents:
18372
diff
changeset
|
2727 shorten_dir(NameBuff); |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
2728 siemsg(_(e_ml_get_cannot_find_line_nr_in_buffer_nr_str), |
18459
5c0437acebb7
patch 8.1.2223: cannot see what buffer an ml_get error is for
Bram Moolenaar <Bram@vim.org>
parents:
18372
diff
changeset
|
2729 lnum, buf->b_fnum, NameBuff); |
1068 | 2730 --recursive; |
2731 } | |
7 | 2732 goto errorret; |
2733 } | |
2734 | |
2735 dp = (DATA_BL *)(hp->bh_data); | |
2736 | |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2737 idx = lnum - buf->b_ml.ml_locked_low; |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2738 start = ((dp->db_index[idx]) & DB_INDEX_MASK); |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2739 // The text ends where the previous line starts. The first line ends |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2740 // at the end of the block. |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2741 if (idx == 0) |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2742 end = dp->db_txt_end; |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2743 else |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2744 end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK); |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2745 len = end - start; |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2746 |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2747 buf->b_ml.ml_line_ptr = (char_u *)dp + start; |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2748 buf->b_ml.ml_line_len = len; |
7 | 2749 buf->b_ml.ml_line_lnum = lnum; |
29340
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2750 buf->b_ml.ml_flags &= ~(ML_LINE_DIRTY | ML_ALLOCATED); |
7 | 2751 } |
2752 if (will_change) | |
29340
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2753 { |
7 | 2754 buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS); |
29340
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2755 #ifdef FEAT_EVAL |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2756 if (ml_get_alloc_lines && (buf->b_ml.ml_flags & ML_ALLOCATED)) |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2757 // can't make the change in the data block |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2758 buf->b_ml.ml_flags |= ML_LINE_DIRTY; |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2759 #endif |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2760 } |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2761 |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2762 #ifdef FEAT_EVAL |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2763 if (ml_get_alloc_lines |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2764 && (buf->b_ml.ml_flags & (ML_LINE_DIRTY | ML_ALLOCATED)) == 0) |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2765 { |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2766 char_u *p = alloc(buf->b_ml.ml_line_len); |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2767 |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2768 // make sure the text is in allocated memory |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2769 if (p != NULL) |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2770 { |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2771 memmove(p, buf->b_ml.ml_line_ptr, buf->b_ml.ml_line_len); |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2772 buf->b_ml.ml_line_ptr = p; |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2773 buf->b_ml.ml_flags |= ML_ALLOCATED; |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2774 if (will_change) |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2775 // can't make the change in the data block |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2776 buf->b_ml.ml_flags |= ML_LINE_DIRTY; |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2777 } |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2778 } |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2779 #endif |
7 | 2780 return buf->b_ml.ml_line_ptr; |
2781 } | |
2782 | |
2783 /* | |
2784 * Check if a line that was just obtained by a call to ml_get | |
2785 * is in allocated memory. | |
29340
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2786 * This ignores ML_ALLOCATED to get the same behavior as without the test |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
2787 * override. |
7 | 2788 */ |
2789 int | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2790 ml_line_alloced(void) |
7 | 2791 { |
2792 return (curbuf->b_ml.ml_flags & ML_LINE_DIRTY); | |
2793 } | |
2794 | |
18763
49b78d6465e5
patch 8.1.2371: FEAT_TEXT_PROP is a confusing name
Bram Moolenaar <Bram@vim.org>
parents:
18498
diff
changeset
|
2795 #ifdef FEAT_PROP_POPUP |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
2796 /* |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
2797 * Add text properties that continue from the previous line. |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
2798 */ |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2799 static void |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2800 add_text_props_for_append( |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2801 buf_T *buf, |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2802 linenr_T lnum, |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2803 char_u **line, |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2804 int *len, |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2805 char_u **tofree) |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2806 { |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2807 int round; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2808 int new_prop_count = 0; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2809 int count; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2810 int n; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2811 char_u *props; |
17974
9fb236d0f386
patch 8.1.1983: compiler nags for uninitialized variable and unused function
Bram Moolenaar <Bram@vim.org>
parents:
17632
diff
changeset
|
2812 int new_len = 0; // init for gcc |
22242
f7871f02ddcd
patch 8.2.1670: a couple of gcc compiler warnings
Bram Moolenaar <Bram@vim.org>
parents:
21915
diff
changeset
|
2813 char_u *new_line = NULL; |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2814 textprop_T prop; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2815 |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2816 // Make two rounds: |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2817 // 1. calculate the extra space needed |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2818 // 2. allocate the space and fill it |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2819 for (round = 1; round <= 2; ++round) |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2820 { |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2821 if (round == 2) |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2822 { |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2823 if (new_prop_count == 0) |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2824 return; // nothing to do |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2825 new_len = *len + new_prop_count * sizeof(textprop_T); |
16764
ef00b6bc186b
patch 8.1.1384: using "int" for alloc() often results in compiler warnings
Bram Moolenaar <Bram@vim.org>
parents:
16738
diff
changeset
|
2826 new_line = alloc(new_len); |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2827 if (new_line == NULL) |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2828 return; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2829 mch_memmove(new_line, *line, *len); |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2830 new_prop_count = 0; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2831 } |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2832 |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2833 // Get the line above to find any props that continue in the next |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2834 // line. |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2835 count = get_text_props(buf, lnum, &props, FALSE); |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2836 for (n = 0; n < count; ++n) |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2837 { |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
2838 mch_memmove(&prop, props + n * sizeof(textprop_T), |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
2839 sizeof(textprop_T)); |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2840 if (prop.tp_flags & TP_FLAG_CONT_NEXT) |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2841 { |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2842 if (round == 2) |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2843 { |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2844 prop.tp_flags |= TP_FLAG_CONT_PREV; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2845 prop.tp_col = 1; |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
2846 prop.tp_len = *len; // not exactly the right length |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
2847 mch_memmove(new_line + *len + new_prop_count |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
2848 * sizeof(textprop_T), &prop, sizeof(textprop_T)); |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2849 } |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2850 ++new_prop_count; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2851 } |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2852 } |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2853 } |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2854 *line = new_line; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2855 *tofree = new_line; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2856 *len = new_len; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2857 } |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2858 #endif |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2859 |
7 | 2860 static int |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2861 ml_append_int( |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
2862 buf_T *buf, |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2863 linenr_T lnum, // append after this line (can be 0) |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2864 char_u *line_arg, // text of the new line |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2865 colnr_T len_arg, // length of line, including NUL, or 0 |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
2866 int flags) // ML_APPEND_ flags |
7 | 2867 { |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2868 char_u *line = line_arg; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2869 colnr_T len = len_arg; |
7 | 2870 int i; |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2871 int line_count; // number of indexes in current block |
7 | 2872 int offset; |
2873 int from, to; | |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2874 int space_needed; // space needed for new line |
7 | 2875 int page_size; |
2876 int page_count; | |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2877 int db_idx; // index for lnum in data block |
7 | 2878 bhdr_T *hp; |
2879 memfile_T *mfp; | |
2880 DATA_BL *dp; | |
2881 PTR_BL *pp; | |
2882 infoptr_T *ip; | |
18763
49b78d6465e5
patch 8.1.2371: FEAT_TEXT_PROP is a confusing name
Bram Moolenaar <Bram@vim.org>
parents:
18498
diff
changeset
|
2883 #ifdef FEAT_PROP_POPUP |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2884 char_u *tofree = NULL; |
29651
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2885 # ifdef FEAT_BYTEOFF |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2886 colnr_T text_len = 0; // text len with NUL without text properties |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2887 # endif |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2888 #endif |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2889 int ret = FAIL; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2890 |
7 | 2891 if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL) |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2892 return FAIL; // lnum out of range |
7 | 2893 |
2894 if (lowest_marked && lowest_marked > lnum) | |
2895 lowest_marked = lnum + 1; | |
2896 | |
2897 if (len == 0) | |
29651
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2898 { |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2899 len = (colnr_T)STRLEN(line) + 1; // space needed for the text |
29651
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2900 #if defined(FEAT_PROP_POPUP) && defined(FEAT_BYTEOFF) |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2901 text_len = len; |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2902 #endif |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2903 } |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2904 #if defined(FEAT_PROP_POPUP) && defined(FEAT_BYTEOFF) |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2905 else if (curbuf->b_has_textprop) |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2906 // "len" may include text properties, get the length of the text. |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2907 text_len = (colnr_T)STRLEN(line) + 1; |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2908 else |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2909 text_len = len; |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
2910 #endif |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2911 |
18763
49b78d6465e5
patch 8.1.2371: FEAT_TEXT_PROP is a confusing name
Bram Moolenaar <Bram@vim.org>
parents:
18498
diff
changeset
|
2912 #ifdef FEAT_PROP_POPUP |
24703
4bc0bda6857d
patch 8.2.2890: text property duplicated when data block splits
Bram Moolenaar <Bram@vim.org>
parents:
24093
diff
changeset
|
2913 if (curbuf->b_has_textprop && lnum > 0 |
4bc0bda6857d
patch 8.2.2890: text property duplicated when data block splits
Bram Moolenaar <Bram@vim.org>
parents:
24093
diff
changeset
|
2914 && !(flags & (ML_APPEND_UNDO | ML_APPEND_NOPROP))) |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2915 // Add text properties that continue from the previous line. |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2916 add_text_props_for_append(buf, lnum, &line, &len, &tofree); |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2917 #endif |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2918 |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
2919 space_needed = len + INDEX_SIZE; // space needed for text + index |
7 | 2920 |
2921 mfp = buf->b_ml.ml_mfp; | |
2922 page_size = mfp->mf_page_size; | |
2923 | |
2924 /* | |
2925 * find the data block containing the previous line | |
2926 * This also fills the stack with the blocks from the root to the data block | |
2927 * This also releases any locked block. | |
2928 */ | |
2929 if ((hp = ml_find_line(buf, lnum == 0 ? (linenr_T)1 : lnum, | |
2930 ML_INSERT)) == NULL) | |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2931 goto theend; |
7 | 2932 |
2933 buf->b_ml.ml_flags &= ~ML_EMPTY; | |
2934 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2935 if (lnum == 0) // got line one instead, correct db_idx |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2936 db_idx = -1; // careful, it is negative! |
7 | 2937 else |
2938 db_idx = lnum - buf->b_ml.ml_locked_low; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2939 // get line count before the insertion |
7 | 2940 line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low; |
2941 | |
2942 dp = (DATA_BL *)(hp->bh_data); | |
2943 | |
2944 /* | |
2945 * If | |
2946 * - there is not enough room in the current block | |
2947 * - appending to the last line in the block | |
2948 * - not appending to the last line in the file | |
2949 * insert in front of the next block. | |
2950 */ | |
2951 if ((int)dp->db_free < space_needed && db_idx == line_count - 1 | |
2952 && lnum < buf->b_ml.ml_line_count) | |
2953 { | |
2954 /* | |
2955 * Now that the line is not going to be inserted in the block that we | |
2956 * expected, the line count has to be adjusted in the pointer blocks | |
2957 * by using ml_locked_lineadd. | |
2958 */ | |
2959 --(buf->b_ml.ml_locked_lineadd); | |
2960 --(buf->b_ml.ml_locked_high); | |
2961 if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL) | |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2962 goto theend; |
7 | 2963 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2964 db_idx = -1; // careful, it is negative! |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2965 // get line count before the insertion |
7 | 2966 line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low; |
2967 CHECK(buf->b_ml.ml_locked_low != lnum + 1, "locked_low != lnum + 1"); | |
2968 | |
2969 dp = (DATA_BL *)(hp->bh_data); | |
2970 } | |
2971 | |
2972 ++buf->b_ml.ml_line_count; | |
2973 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2974 if ((int)dp->db_free >= space_needed) // enough room in data block |
7 | 2975 { |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2976 /* |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2977 * Insert the new line in an existing data block, or in the data block |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2978 * allocated above. |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
2979 */ |
7 | 2980 dp->db_txt_start -= len; |
2981 dp->db_free -= space_needed; | |
2982 ++(dp->db_line_count); | |
2983 | |
2984 /* | |
2985 * move the text of the lines that follow to the front | |
2986 * adjust the indexes of the lines that follow | |
2987 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
2988 if (line_count > db_idx + 1) // if there are following lines |
7 | 2989 { |
2990 /* | |
2991 * Offset is the start of the previous line. | |
2992 * This will become the character just after the new line. | |
2993 */ | |
2994 if (db_idx < 0) | |
2995 offset = dp->db_txt_end; | |
2996 else | |
2997 offset = ((dp->db_index[db_idx]) & DB_INDEX_MASK); | |
2998 mch_memmove((char *)dp + dp->db_txt_start, | |
2999 (char *)dp + dp->db_txt_start + len, | |
3000 (size_t)(offset - (dp->db_txt_start + len))); | |
3001 for (i = line_count - 1; i > db_idx; --i) | |
3002 dp->db_index[i + 1] = dp->db_index[i] - len; | |
3003 dp->db_index[db_idx + 1] = offset - len; | |
3004 } | |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3005 else |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3006 // add line at the end (which is the start of the text) |
7 | 3007 dp->db_index[db_idx + 1] = dp->db_txt_start; |
3008 | |
3009 /* | |
3010 * copy the text into the block | |
3011 */ | |
3012 mch_memmove((char *)dp + dp->db_index[db_idx + 1], line, (size_t)len); | |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3013 if (flags & ML_APPEND_MARK) |
7 | 3014 dp->db_index[db_idx + 1] |= DB_MARKED; |
3015 | |
3016 /* | |
3017 * Mark the block dirty. | |
3018 */ | |
3019 buf->b_ml.ml_flags |= ML_LOCKED_DIRTY; | |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3020 if (!(flags & ML_APPEND_NEW)) |
7 | 3021 buf->b_ml.ml_flags |= ML_LOCKED_POS; |
3022 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3023 else // not enough space in data block |
7 | 3024 { |
3025 long line_count_left, line_count_right; | |
3026 int page_count_left, page_count_right; | |
3027 bhdr_T *hp_left; | |
3028 bhdr_T *hp_right; | |
3029 bhdr_T *hp_new; | |
3030 int lines_moved; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3031 int data_moved = 0; // init to shut up gcc |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3032 int total_moved = 0; // init to shut up gcc |
7 | 3033 DATA_BL *dp_right, *dp_left; |
3034 int stack_idx; | |
3035 int in_left; | |
3036 int lineadd; | |
3037 blocknr_T bnum_left, bnum_right; | |
3038 linenr_T lnum_left, lnum_right; | |
3039 int pb_idx; | |
3040 PTR_BL *pp_new; | |
3041 | |
3042 /* | |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3043 * There is not enough room, we have to create a new data block and |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3044 * copy some lines into it. |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3045 * Then we have to insert an entry in the pointer block. |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3046 * If this pointer block also is full, we go up another block, and so |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3047 * on, up to the root if necessary. |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3048 * The line counts in the pointer blocks have already been adjusted by |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3049 * ml_find_line(). |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3050 * |
7 | 3051 * We are going to allocate a new data block. Depending on the |
3052 * situation it will be put to the left or right of the existing | |
3053 * block. If possible we put the new line in the left block and move | |
3054 * the lines after it to the right block. Otherwise the new line is | |
3055 * also put in the right block. This method is more efficient when | |
3056 * inserting a lot of lines at one place. | |
3057 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3058 if (db_idx < 0) // left block is new, right block is existing |
7 | 3059 { |
3060 lines_moved = 0; | |
3061 in_left = TRUE; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3062 // space_needed does not change |
7 | 3063 } |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3064 else // left block is existing, right block is new |
7 | 3065 { |
3066 lines_moved = line_count - db_idx - 1; | |
3067 if (lines_moved == 0) | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3068 in_left = FALSE; // put new line in right block |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3069 // space_needed does not change |
7 | 3070 else |
3071 { | |
3072 data_moved = ((dp->db_index[db_idx]) & DB_INDEX_MASK) - | |
3073 dp->db_txt_start; | |
3074 total_moved = data_moved + lines_moved * INDEX_SIZE; | |
3075 if ((int)dp->db_free + total_moved >= space_needed) | |
3076 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3077 in_left = TRUE; // put new line in left block |
7 | 3078 space_needed = total_moved; |
3079 } | |
3080 else | |
3081 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3082 in_left = FALSE; // put new line in right block |
7 | 3083 space_needed += total_moved; |
3084 } | |
3085 } | |
3086 } | |
3087 | |
3088 page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size; | |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3089 if ((hp_new = ml_new_data(mfp, flags & ML_APPEND_NEW, page_count)) |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3090 == NULL) |
7 | 3091 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3092 // correct line counts in pointer blocks |
7 | 3093 --(buf->b_ml.ml_locked_lineadd); |
3094 --(buf->b_ml.ml_locked_high); | |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3095 goto theend; |
7 | 3096 } |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3097 if (db_idx < 0) // left block is new |
7 | 3098 { |
3099 hp_left = hp_new; | |
3100 hp_right = hp; | |
3101 line_count_left = 0; | |
3102 line_count_right = line_count; | |
3103 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3104 else // right block is new |
7 | 3105 { |
3106 hp_left = hp; | |
3107 hp_right = hp_new; | |
3108 line_count_left = line_count; | |
3109 line_count_right = 0; | |
3110 } | |
3111 dp_right = (DATA_BL *)(hp_right->bh_data); | |
3112 dp_left = (DATA_BL *)(hp_left->bh_data); | |
3113 bnum_left = hp_left->bh_bnum; | |
3114 bnum_right = hp_right->bh_bnum; | |
3115 page_count_left = hp_left->bh_page_count; | |
3116 page_count_right = hp_right->bh_page_count; | |
3117 | |
3118 /* | |
3119 * May move the new line into the right/new block. | |
3120 */ | |
3121 if (!in_left) | |
3122 { | |
3123 dp_right->db_txt_start -= len; | |
3124 dp_right->db_free -= len + INDEX_SIZE; | |
3125 dp_right->db_index[0] = dp_right->db_txt_start; | |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3126 if (flags & ML_APPEND_MARK) |
7 | 3127 dp_right->db_index[0] |= DB_MARKED; |
3128 | |
3129 mch_memmove((char *)dp_right + dp_right->db_txt_start, | |
3130 line, (size_t)len); | |
3131 ++line_count_right; | |
3132 } | |
3133 /* | |
3134 * may move lines from the left/old block to the right/new one. | |
3135 */ | |
3136 if (lines_moved) | |
3137 { | |
3138 dp_right->db_txt_start -= data_moved; | |
3139 dp_right->db_free -= total_moved; | |
3140 mch_memmove((char *)dp_right + dp_right->db_txt_start, | |
3141 (char *)dp_left + dp_left->db_txt_start, | |
3142 (size_t)data_moved); | |
3143 offset = dp_right->db_txt_start - dp_left->db_txt_start; | |
3144 dp_left->db_txt_start += data_moved; | |
3145 dp_left->db_free += total_moved; | |
3146 | |
3147 /* | |
3148 * update indexes in the new block | |
3149 */ | |
3150 for (to = line_count_right, from = db_idx + 1; | |
3151 from < line_count_left; ++from, ++to) | |
3152 dp_right->db_index[to] = dp->db_index[from] + offset; | |
3153 line_count_right += lines_moved; | |
3154 line_count_left -= lines_moved; | |
3155 } | |
3156 | |
3157 /* | |
3158 * May move the new line into the left (old or new) block. | |
3159 */ | |
3160 if (in_left) | |
3161 { | |
3162 dp_left->db_txt_start -= len; | |
3163 dp_left->db_free -= len + INDEX_SIZE; | |
3164 dp_left->db_index[line_count_left] = dp_left->db_txt_start; | |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3165 if (flags & ML_APPEND_MARK) |
7 | 3166 dp_left->db_index[line_count_left] |= DB_MARKED; |
3167 mch_memmove((char *)dp_left + dp_left->db_txt_start, | |
3168 line, (size_t)len); | |
3169 ++line_count_left; | |
3170 } | |
3171 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3172 if (db_idx < 0) // left block is new |
7 | 3173 { |
3174 lnum_left = lnum + 1; | |
3175 lnum_right = 0; | |
3176 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3177 else // right block is new |
7 | 3178 { |
3179 lnum_left = 0; | |
3180 if (in_left) | |
3181 lnum_right = lnum + 2; | |
3182 else | |
3183 lnum_right = lnum + 1; | |
3184 } | |
3185 dp_left->db_line_count = line_count_left; | |
3186 dp_right->db_line_count = line_count_right; | |
3187 | |
3188 /* | |
3189 * release the two data blocks | |
3190 * The new one (hp_new) already has a correct blocknumber. | |
3191 * The old one (hp, in ml_locked) gets a positive blocknumber if | |
3192 * we changed it and we are not editing a new file. | |
3193 */ | |
3194 if (lines_moved || in_left) | |
3195 buf->b_ml.ml_flags |= ML_LOCKED_DIRTY; | |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3196 if (!(flags & ML_APPEND_NEW) && db_idx >= 0 && in_left) |
7 | 3197 buf->b_ml.ml_flags |= ML_LOCKED_POS; |
3198 mf_put(mfp, hp_new, TRUE, FALSE); | |
3199 | |
3200 /* | |
3201 * flush the old data block | |
3202 * set ml_locked_lineadd to 0, because the updating of the | |
3203 * pointer blocks is done below | |
3204 */ | |
3205 lineadd = buf->b_ml.ml_locked_lineadd; | |
3206 buf->b_ml.ml_locked_lineadd = 0; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3207 ml_find_line(buf, (linenr_T)0, ML_FLUSH); // flush data block |
7 | 3208 |
3209 /* | |
3210 * update pointer blocks for the new data block | |
3211 */ | |
3212 for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0; | |
3213 --stack_idx) | |
3214 { | |
3215 ip = &(buf->b_ml.ml_stack[stack_idx]); | |
3216 pb_idx = ip->ip_index; | |
3217 if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) | |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3218 goto theend; |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3219 pp = (PTR_BL *)(hp->bh_data); // must be pointer block |
7 | 3220 if (pp->pb_id != PTR_ID) |
3221 { | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
3222 iemsg(_(e_pointer_block_id_wrong_three)); |
7 | 3223 mf_put(mfp, hp, FALSE, FALSE); |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3224 goto theend; |
7 | 3225 } |
3226 /* | |
3227 * TODO: If the pointer block is full and we are adding at the end | |
3228 * try to insert in front of the next block | |
3229 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3230 // block not full, add one entry |
7 | 3231 if (pp->pb_count < pp->pb_count_max) |
3232 { | |
3233 if (pb_idx + 1 < (int)pp->pb_count) | |
3234 mch_memmove(&pp->pb_pointer[pb_idx + 2], | |
3235 &pp->pb_pointer[pb_idx + 1], | |
3236 (size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN)); | |
3237 ++pp->pb_count; | |
3238 pp->pb_pointer[pb_idx].pe_line_count = line_count_left; | |
3239 pp->pb_pointer[pb_idx].pe_bnum = bnum_left; | |
3240 pp->pb_pointer[pb_idx].pe_page_count = page_count_left; | |
3241 pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right; | |
3242 pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right; | |
3243 pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right; | |
3244 | |
3245 if (lnum_left != 0) | |
3246 pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left; | |
3247 if (lnum_right != 0) | |
3248 pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right; | |
3249 | |
3250 mf_put(mfp, hp, TRUE, FALSE); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3251 buf->b_ml.ml_stack_top = stack_idx + 1; // truncate stack |
7 | 3252 |
3253 if (lineadd) | |
3254 { | |
3255 --(buf->b_ml.ml_stack_top); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3256 // fix line count for rest of blocks in the stack |
7 | 3257 ml_lineadd(buf, lineadd); |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3258 // fix stack itself |
7 | 3259 buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high += |
3260 lineadd; | |
3261 ++(buf->b_ml.ml_stack_top); | |
3262 } | |
3263 | |
3264 /* | |
3265 * We are finished, break the loop here. | |
3266 */ | |
3267 break; | |
3268 } | |
28357
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3269 // pointer block full |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3270 /* |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3271 * split the pointer block |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3272 * allocate a new pointer block |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3273 * move some of the pointer into the new block |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3274 * prepare for updating the parent block |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3275 */ |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3276 for (;;) // do this twice when splitting block 1 |
7 | 3277 { |
28357
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3278 hp_new = ml_new_ptr(mfp); |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3279 if (hp_new == NULL) // TODO: try to fix tree |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3280 goto theend; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3281 pp_new = (PTR_BL *)(hp_new->bh_data); |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3282 |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3283 if (hp->bh_bnum != 1) |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3284 break; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3285 |
7 | 3286 /* |
28357
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3287 * if block 1 becomes full the tree is given an extra level |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3288 * The pointers from block 1 are moved into the new block. |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3289 * block 1 is updated to point to the new block |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3290 * then continue to split the new block |
7 | 3291 */ |
28357
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3292 mch_memmove(pp_new, pp, (size_t)page_size); |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3293 pp->pb_count = 1; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3294 pp->pb_pointer[0].pe_bnum = hp_new->bh_bnum; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3295 pp->pb_pointer[0].pe_line_count = buf->b_ml.ml_line_count; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3296 pp->pb_pointer[0].pe_old_lnum = 1; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3297 pp->pb_pointer[0].pe_page_count = 1; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3298 mf_put(mfp, hp, TRUE, FALSE); // release block 1 |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3299 hp = hp_new; // new block is to be split |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3300 pp = pp_new; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3301 CHECK(stack_idx != 0, _("stack_idx should be 0")); |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3302 ip->ip_index = 0; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3303 ++stack_idx; // do block 1 again later |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3304 } |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3305 /* |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3306 * move the pointers after the current one to the new block |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3307 * If there are none, the new entry will be in the new block. |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3308 */ |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3309 total_moved = pp->pb_count - pb_idx - 1; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3310 if (total_moved) |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3311 { |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3312 mch_memmove(&pp_new->pb_pointer[0], |
7 | 3313 &pp->pb_pointer[pb_idx + 1], |
3314 (size_t)(total_moved) * sizeof(PTR_EN)); | |
28357
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3315 pp_new->pb_count = total_moved; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3316 pp->pb_count -= total_moved - 1; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3317 pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3318 pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3319 pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3320 if (lnum_right) |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3321 pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3322 } |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3323 else |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3324 { |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3325 pp_new->pb_count = 1; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3326 pp_new->pb_pointer[0].pe_bnum = bnum_right; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3327 pp_new->pb_pointer[0].pe_line_count = line_count_right; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3328 pp_new->pb_pointer[0].pe_page_count = page_count_right; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3329 pp_new->pb_pointer[0].pe_old_lnum = lnum_right; |
7 | 3330 } |
28357
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3331 pp->pb_pointer[pb_idx].pe_bnum = bnum_left; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3332 pp->pb_pointer[pb_idx].pe_line_count = line_count_left; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3333 pp->pb_pointer[pb_idx].pe_page_count = page_count_left; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3334 if (lnum_left) |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3335 pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3336 lnum_left = 0; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3337 lnum_right = 0; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3338 |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3339 /* |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3340 * recompute line counts |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3341 */ |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3342 line_count_right = 0; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3343 for (i = 0; i < (int)pp_new->pb_count; ++i) |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3344 line_count_right += pp_new->pb_pointer[i].pe_line_count; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3345 line_count_left = 0; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3346 for (i = 0; i < (int)pp->pb_count; ++i) |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3347 line_count_left += pp->pb_pointer[i].pe_line_count; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3348 |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3349 bnum_left = hp->bh_bnum; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3350 bnum_right = hp_new->bh_bnum; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3351 page_count_left = 1; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3352 page_count_right = 1; |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3353 mf_put(mfp, hp, TRUE, FALSE); |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3354 mf_put(mfp, hp_new, TRUE, FALSE); |
86b6432aa1d8
patch 8.2.4704: using "else" after return or break increases indent
Bram Moolenaar <Bram@vim.org>
parents:
28319
diff
changeset
|
3355 |
7 | 3356 } |
3357 | |
3358 /* | |
3359 * Safety check: fallen out of for loop? | |
3360 */ | |
3361 if (stack_idx < 0) | |
3362 { | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
3363 iemsg(_(e_updated_too_many_blocks)); |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3364 buf->b_ml.ml_stack_top = 0; // invalidate stack |
7 | 3365 } |
3366 } | |
3367 | |
3368 #ifdef FEAT_BYTEOFF | |
29651
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
3369 // The line was inserted below 'lnum' |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
3370 ml_updatechunk(buf, lnum + 1, |
25672
ab42c36d1a27
patch 8.2.3372: line2byte() value wrong when adding a text property
Bram Moolenaar <Bram@vim.org>
parents:
25638
diff
changeset
|
3371 # ifdef FEAT_PROP_POPUP |
29651
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
3372 (long)text_len |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
3373 # else |
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
3374 (long)len |
29682
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
3375 # endif |
29651
23dceecc0bf8
patch 9.0.0166: when using text properties line text length computed twice
Bram Moolenaar <Bram@vim.org>
parents:
29340
diff
changeset
|
3376 , ML_CHNK_ADDLINE); |
7 | 3377 #endif |
25672
ab42c36d1a27
patch 8.2.3372: line2byte() value wrong when adding a text property
Bram Moolenaar <Bram@vim.org>
parents:
25638
diff
changeset
|
3378 |
7 | 3379 #ifdef FEAT_NETBEANS_INTG |
2210 | 3380 if (netbeans_active()) |
7 | 3381 { |
3382 if (STRLEN(line) > 0) | |
835 | 3383 netbeans_inserted(buf, lnum+1, (colnr_T)0, line, (int)STRLEN(line)); |
34 | 3384 netbeans_inserted(buf, lnum+1, (colnr_T)STRLEN(line), |
7 | 3385 (char_u *)"\n", 1); |
3386 } | |
3387 #endif | |
8493
caed4b2d305f
commit https://github.com/vim/vim/commit/509ce2a558e7e0c03242e32e844255af52f1c821
Christian Brabandt <cb@256bit.org>
parents:
8422
diff
changeset
|
3388 #ifdef FEAT_JOB_CHANNEL |
8422
5d2c84be23b5
commit https://github.com/vim/vim/commit/99ef06296f3c37490511c03786a2c8672e015c56
Christian Brabandt <cb@256bit.org>
parents:
8212
diff
changeset
|
3389 if (buf->b_write_to_channel) |
5d2c84be23b5
commit https://github.com/vim/vim/commit/99ef06296f3c37490511c03786a2c8672e015c56
Christian Brabandt <cb@256bit.org>
parents:
8212
diff
changeset
|
3390 channel_write_new_lines(buf); |
5d2c84be23b5
commit https://github.com/vim/vim/commit/99ef06296f3c37490511c03786a2c8672e015c56
Christian Brabandt <cb@256bit.org>
parents:
8212
diff
changeset
|
3391 #endif |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3392 ret = OK; |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3393 |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3394 theend: |
18763
49b78d6465e5
patch 8.1.2371: FEAT_TEXT_PROP is a confusing name
Bram Moolenaar <Bram@vim.org>
parents:
18498
diff
changeset
|
3395 #ifdef FEAT_PROP_POPUP |
15294
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3396 vim_free(tofree); |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3397 #endif |
2d8225cc1315
patch 8.1.0655: when appending a line text property flags are not added
Bram Moolenaar <Bram@vim.org>
parents:
15292
diff
changeset
|
3398 return ret; |
7 | 3399 } |
3400 | |
3401 /* | |
17403
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3402 * Flush any pending change and call ml_append_int() |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3403 */ |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3404 static int |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3405 ml_append_flush( |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3406 buf_T *buf, |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3407 linenr_T lnum, // append after this line (can be 0) |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3408 char_u *line, // text of the new line |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3409 colnr_T len, // length of line, including NUL, or 0 |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3410 int flags) // ML_APPEND_ flags |
17403
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3411 { |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3412 if (lnum > buf->b_ml.ml_line_count) |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3413 return FAIL; // lnum out of range |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3414 |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3415 if (buf->b_ml.ml_line_lnum != 0) |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3416 // This may also invoke ml_append_int(). |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3417 ml_flush_line(buf); |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3418 |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3419 #ifdef FEAT_EVAL |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3420 // When inserting above recorded changes: flush the changes before changing |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3421 // the text. Then flush the cached line, it may become invalid. |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3422 may_invoke_listeners(buf, lnum + 1, lnum + 1, 1); |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3423 if (buf->b_ml.ml_line_lnum != 0) |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3424 ml_flush_line(buf); |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3425 #endif |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3426 |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3427 return ml_append_int(buf, lnum, line, len, flags); |
17403
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3428 } |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3429 |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3430 /* |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3431 * Append a line after lnum (may be 0 to insert a line in front of the file). |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3432 * "line" does not need to be allocated, but can't be another line in a |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3433 * buffer, unlocking may make it invalid. |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3434 * |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3435 * "newfile": TRUE when starting to edit a new file, meaning that pe_old_lnum |
17403
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3436 * will be set for recovery |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3437 * Check: The caller of this function should probably also call |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3438 * appended_lines(). |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3439 * |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3440 * return FAIL for failure, OK otherwise |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3441 */ |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3442 int |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3443 ml_append( |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3444 linenr_T lnum, // append after this line (can be 0) |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3445 char_u *line, // text of the new line |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3446 colnr_T len, // length of new line, including NUL, or 0 |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3447 int newfile) // flag, see above |
17403
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3448 { |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3449 return ml_append_flags(lnum, line, len, newfile ? ML_APPEND_NEW : 0); |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3450 } |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3451 |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3452 int |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3453 ml_append_flags( |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3454 linenr_T lnum, // append after this line (can be 0) |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3455 char_u *line, // text of the new line |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3456 colnr_T len, // length of new line, including NUL, or 0 |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3457 int flags) // ML_APPEND_ values |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3458 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3459 // When starting up, we might still need to create the memfile |
17403
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3460 if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL) |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3461 return FAIL; |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3462 return ml_append_flush(curbuf, lnum, line, len, flags); |
17403
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3463 } |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3464 |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3465 |
28877
f13fcdacb57f
patch 8.2.4961: build error with a certain combination of features
Bram Moolenaar <Bram@vim.org>
parents:
28875
diff
changeset
|
3466 #if defined(FEAT_SPELL) || defined(FEAT_QUICKFIX) || defined(FEAT_PROP_POPUP) \ |
f13fcdacb57f
patch 8.2.4961: build error with a certain combination of features
Bram Moolenaar <Bram@vim.org>
parents:
28875
diff
changeset
|
3467 || defined(PROTO) |
17403
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3468 /* |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3469 * Like ml_append() but for an arbitrary buffer. The buffer must already have |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3470 * a memline. |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3471 */ |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3472 int |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3473 ml_append_buf( |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3474 buf_T *buf, |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3475 linenr_T lnum, // append after this line (can be 0) |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3476 char_u *line, // text of the new line |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3477 colnr_T len, // length of new line, including NUL, or 0 |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3478 int newfile) // flag, see above |
17403
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3479 { |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3480 if (buf->b_ml.ml_mfp == NULL) |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3481 return FAIL; |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3482 return ml_append_flush(buf, lnum, line, len, newfile ? ML_APPEND_NEW : 0); |
17403
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3483 } |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3484 #endif |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3485 |
9b6c0ef29c20
patch 8.1.1700: listener callback called for the wrong buffer
Bram Moolenaar <Bram@vim.org>
parents:
17364
diff
changeset
|
3486 /* |
21337
647897e6df9e
patch 8.2.1219: symlink not followed if dirname ends in //
Bram Moolenaar <Bram@vim.org>
parents:
20830
diff
changeset
|
3487 * Replace line "lnum", with buffering, in current buffer. |
7 | 3488 * |
720 | 3489 * If "copy" is TRUE, make a copy of the line, otherwise the line has been |
7 | 3490 * copied to allocated memory already. |
21337
647897e6df9e
patch 8.2.1219: symlink not followed if dirname ends in //
Bram Moolenaar <Bram@vim.org>
parents:
20830
diff
changeset
|
3491 * If "copy" is FALSE the "line" may be freed to add text properties! |
647897e6df9e
patch 8.2.1219: symlink not followed if dirname ends in //
Bram Moolenaar <Bram@vim.org>
parents:
20830
diff
changeset
|
3492 * Do not use it after calling ml_replace(). |
7 | 3493 * |
3494 * Check: The caller of this function should probably also call | |
29732
89e1d67814a9
patch 9.0.0206: redraw flags are not named specifically
Bram Moolenaar <Bram@vim.org>
parents:
29682
diff
changeset
|
3495 * changed_lines(), unless update_screen(UPD_NOT_VALID) is used. |
7 | 3496 * |
3497 * return FAIL for failure, OK otherwise | |
3498 */ | |
3499 int | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
3500 ml_replace(linenr_T lnum, char_u *line, int copy) |
7 | 3501 { |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3502 colnr_T len = -1; |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3503 |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3504 if (line != NULL) |
15182
4b2de998ebd6
patch 8.1.0601: a few compiler warnings
Bram Moolenaar <Bram@vim.org>
parents:
15142
diff
changeset
|
3505 len = (colnr_T)STRLEN(line); |
15361
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3506 return ml_replace_len(lnum, line, len, FALSE, copy); |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3507 } |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3508 |
15361
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3509 /* |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3510 * Replace a line for the current buffer. Like ml_replace() with: |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3511 * "len_arg" is the length of the text, excluding NUL. |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3512 * If "has_props" is TRUE then "line_arg" includes the text properties and |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3513 * "len_arg" includes the NUL of the text. |
29340
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
3514 * When "copy" is TRUE copy the text into allocated memory, otherwise |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
3515 * "line_arg" must be allocated and will be consumed here. |
15361
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3516 */ |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3517 int |
15361
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3518 ml_replace_len( |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3519 linenr_T lnum, |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3520 char_u *line_arg, |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3521 colnr_T len_arg, |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3522 int has_props, |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3523 int copy) |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3524 { |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3525 char_u *line = line_arg; |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3526 colnr_T len = len_arg; |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3527 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3528 if (line == NULL) // just checking... |
7 | 3529 return FAIL; |
3530 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3531 // When starting up, we might still need to create the memfile |
2394
a3aca345aafa
Add the 'undoreload' option to be able to undo a file reload.
Bram Moolenaar <bram@vim.org>
parents:
2360
diff
changeset
|
3532 if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL) |
7 | 3533 return FAIL; |
3534 | |
15361
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3535 if (!has_props) |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3536 ++len; // include the NUL after the text |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3537 if (copy) |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3538 { |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3539 // copy the line to allocated memory |
18763
49b78d6465e5
patch 8.1.2371: FEAT_TEXT_PROP is a confusing name
Bram Moolenaar <Bram@vim.org>
parents:
18498
diff
changeset
|
3540 #ifdef FEAT_PROP_POPUP |
15361
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3541 if (has_props) |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3542 line = vim_memsave(line, len); |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3543 else |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3544 #endif |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3545 line = vim_strnsave(line, len - 1); |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3546 if (line == NULL) |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3547 return FAIL; |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3548 } |
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3549 |
7 | 3550 #ifdef FEAT_NETBEANS_INTG |
2210 | 3551 if (netbeans_active()) |
7 | 3552 { |
3553 netbeans_removed(curbuf, lnum, 0, (long)STRLEN(ml_get(lnum))); | |
835 | 3554 netbeans_inserted(curbuf, lnum, 0, line, (int)STRLEN(line)); |
7 | 3555 } |
3556 #endif | |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3557 if (curbuf->b_ml.ml_line_lnum != lnum) |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3558 { |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3559 // another line is buffered, flush it |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3560 ml_flush_line(curbuf); |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3561 |
18763
49b78d6465e5
patch 8.1.2371: FEAT_TEXT_PROP is a confusing name
Bram Moolenaar <Bram@vim.org>
parents:
18498
diff
changeset
|
3562 #ifdef FEAT_PROP_POPUP |
15361
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3563 if (curbuf->b_has_textprop && !has_props) |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3564 // Need to fetch the old line to copy over any text properties. |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3565 ml_get_buf(curbuf, lnum, TRUE); |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3566 #endif |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3567 } |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3568 |
18763
49b78d6465e5
patch 8.1.2371: FEAT_TEXT_PROP is a confusing name
Bram Moolenaar <Bram@vim.org>
parents:
18498
diff
changeset
|
3569 #ifdef FEAT_PROP_POPUP |
15361
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3570 if (curbuf->b_has_textprop && !has_props) |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3571 { |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3572 size_t oldtextlen = STRLEN(curbuf->b_ml.ml_line_ptr) + 1; |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3573 |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3574 if (oldtextlen < (size_t)curbuf->b_ml.ml_line_len) |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3575 { |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3576 char_u *newline; |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3577 size_t textproplen = curbuf->b_ml.ml_line_len - oldtextlen; |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3578 |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3579 // Need to copy over text properties, stored after the text. |
15361
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3580 newline = alloc(len + (int)textproplen); |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3581 if (newline != NULL) |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3582 { |
15361
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3583 mch_memmove(newline, line, len); |
16684
1c2d9f67d98f
patch 8.1.1344: Coverity complains about possibly using a NULL pointer
Bram Moolenaar <Bram@vim.org>
parents:
16666
diff
changeset
|
3584 mch_memmove(newline + len, curbuf->b_ml.ml_line_ptr |
1c2d9f67d98f
patch 8.1.1344: Coverity complains about possibly using a NULL pointer
Bram Moolenaar <Bram@vim.org>
parents:
16666
diff
changeset
|
3585 + oldtextlen, textproplen); |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3586 vim_free(line); |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3587 line = newline; |
15182
4b2de998ebd6
patch 8.1.0601: a few compiler warnings
Bram Moolenaar <Bram@vim.org>
parents:
15142
diff
changeset
|
3588 len += (colnr_T)textproplen; |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3589 } |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3590 } |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3591 } |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3592 #endif |
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3593 |
29340
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
3594 if (curbuf->b_ml.ml_flags & (ML_LINE_DIRTY | ML_ALLOCATED)) |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
3595 vim_free(curbuf->b_ml.ml_line_ptr); // free allocated line |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
3596 |
7 | 3597 curbuf->b_ml.ml_line_ptr = line; |
15361
58b125df3e9b
patch 8.1.0688: text properties are not restored by undo
Bram Moolenaar <Bram@vim.org>
parents:
15353
diff
changeset
|
3598 curbuf->b_ml.ml_line_len = len; |
7 | 3599 curbuf->b_ml.ml_line_lnum = lnum; |
3600 curbuf->b_ml.ml_flags = (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY; | |
3601 | |
3602 return OK; | |
3603 } | |
3604 | |
18763
49b78d6465e5
patch 8.1.2371: FEAT_TEXT_PROP is a confusing name
Bram Moolenaar <Bram@vim.org>
parents:
18498
diff
changeset
|
3605 #ifdef FEAT_PROP_POPUP |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3606 /* |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3607 * Adjust text properties in line "lnum" for a deleted line. |
28875
78ebb50d6fcb
patch 8.2.4960: text properties that cross lines not updated for deleted line
Bram Moolenaar <Bram@vim.org>
parents:
28457
diff
changeset
|
3608 * When "above" is true this is the line above the deleted line, otherwise this |
78ebb50d6fcb
patch 8.2.4960: text properties that cross lines not updated for deleted line
Bram Moolenaar <Bram@vim.org>
parents:
28457
diff
changeset
|
3609 * is the line below the deleted line. |
78ebb50d6fcb
patch 8.2.4960: text properties that cross lines not updated for deleted line
Bram Moolenaar <Bram@vim.org>
parents:
28457
diff
changeset
|
3610 * "del_props[del_props_len]" are the properties of the deleted line. |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3611 */ |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3612 static void |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3613 adjust_text_props_for_delete( |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3614 buf_T *buf, |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3615 linenr_T lnum, |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3616 char_u *del_props, |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3617 int del_props_len, |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3618 int above) |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3619 { |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3620 int did_get_line = FALSE; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3621 int done_del; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3622 int done_this; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3623 textprop_T prop_del; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3624 bhdr_T *hp; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3625 DATA_BL *dp; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3626 int idx; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3627 int line_start; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3628 long line_size; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3629 int this_props_len; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3630 char_u *text; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3631 size_t textlen; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3632 int found; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3633 |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3634 for (done_del = 0; done_del < del_props_len; done_del += sizeof(textprop_T)) |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3635 { |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3636 mch_memmove(&prop_del, del_props + done_del, sizeof(textprop_T)); |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3637 if ((above && (prop_del.tp_flags & TP_FLAG_CONT_PREV) |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3638 && !(prop_del.tp_flags & TP_FLAG_CONT_NEXT)) |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3639 || (!above && (prop_del.tp_flags & TP_FLAG_CONT_NEXT) |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3640 && !(prop_del.tp_flags & TP_FLAG_CONT_PREV))) |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3641 { |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3642 if (!did_get_line) |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3643 { |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3644 did_get_line = TRUE; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3645 if ((hp = ml_find_line(buf, lnum, ML_FIND)) == NULL) |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3646 return; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3647 |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3648 dp = (DATA_BL *)(hp->bh_data); |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3649 idx = lnum - buf->b_ml.ml_locked_low; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3650 line_start = ((dp->db_index[idx]) & DB_INDEX_MASK); |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3651 if (idx == 0) // first line in block, text at the end |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3652 line_size = dp->db_txt_end - line_start; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3653 else |
20583
d067be761cd7
patch 8.2.0845: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
20581
diff
changeset
|
3654 line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) |
d067be761cd7
patch 8.2.0845: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
20581
diff
changeset
|
3655 - line_start; |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3656 text = (char_u *)dp + line_start; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3657 textlen = STRLEN(text) + 1; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3658 if ((long)textlen >= line_size) |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3659 { |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3660 if (above) |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3661 internal_error("no text property above deleted line"); |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3662 else |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3663 internal_error("no text property below deleted line"); |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3664 return; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3665 } |
15353
21580db06cf3
patch 8.1.0684: warnings from 64-bit compiler
Bram Moolenaar <Bram@vim.org>
parents:
15294
diff
changeset
|
3666 this_props_len = line_size - (int)textlen; |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3667 } |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3668 |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3669 found = FALSE; |
20583
d067be761cd7
patch 8.2.0845: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
20581
diff
changeset
|
3670 for (done_this = 0; done_this < this_props_len; |
d067be761cd7
patch 8.2.0845: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
20581
diff
changeset
|
3671 done_this += sizeof(textprop_T)) |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3672 { |
20583
d067be761cd7
patch 8.2.0845: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
20581
diff
changeset
|
3673 int flag = above ? TP_FLAG_CONT_NEXT |
d067be761cd7
patch 8.2.0845: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
20581
diff
changeset
|
3674 : TP_FLAG_CONT_PREV; |
d067be761cd7
patch 8.2.0845: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
20581
diff
changeset
|
3675 textprop_T prop_this; |
d067be761cd7
patch 8.2.0845: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
20581
diff
changeset
|
3676 |
28875
78ebb50d6fcb
patch 8.2.4960: text properties that cross lines not updated for deleted line
Bram Moolenaar <Bram@vim.org>
parents:
28457
diff
changeset
|
3677 mch_memmove(&prop_this, text + textlen + done_this, |
20583
d067be761cd7
patch 8.2.0845: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
20581
diff
changeset
|
3678 sizeof(textprop_T)); |
d067be761cd7
patch 8.2.0845: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
20581
diff
changeset
|
3679 if ((prop_this.tp_flags & flag) |
d067be761cd7
patch 8.2.0845: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
20581
diff
changeset
|
3680 && prop_del.tp_id == prop_this.tp_id |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3681 && prop_del.tp_type == prop_this.tp_type) |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3682 { |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3683 found = TRUE; |
20583
d067be761cd7
patch 8.2.0845: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
20581
diff
changeset
|
3684 prop_this.tp_flags &= ~flag; |
28875
78ebb50d6fcb
patch 8.2.4960: text properties that cross lines not updated for deleted line
Bram Moolenaar <Bram@vim.org>
parents:
28457
diff
changeset
|
3685 mch_memmove(text + textlen + done_this, &prop_this, |
20583
d067be761cd7
patch 8.2.0845: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
20581
diff
changeset
|
3686 sizeof(textprop_T)); |
d067be761cd7
patch 8.2.0845: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
20581
diff
changeset
|
3687 break; |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3688 } |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3689 } |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3690 if (!found) |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3691 { |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3692 if (above) |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3693 internal_error("text property above deleted line not found"); |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3694 else |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3695 internal_error("text property below deleted line not found"); |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3696 } |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3697 |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3698 buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS); |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3699 } |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3700 } |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3701 } |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3702 #endif |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3703 |
7 | 3704 /* |
12477
68d7bc045dbe
patch 8.0.1118: FEAT_WINDOWS adds a lot of #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
3705 * Delete line "lnum" in the current buffer. |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3706 * When "flags" has ML_DEL_MESSAGE may give a "No lines in buffer" message. |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3707 * When "flags" has ML_DEL_UNDO this is called from undo. |
7 | 3708 * |
3709 * return FAIL for failure, OK otherwise | |
3710 */ | |
3711 static int | |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3712 ml_delete_int(buf_T *buf, linenr_T lnum, int flags) |
7 | 3713 { |
3714 bhdr_T *hp; | |
3715 memfile_T *mfp; | |
3716 DATA_BL *dp; | |
3717 PTR_BL *pp; | |
3718 infoptr_T *ip; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3719 int count; // number of entries in block |
7 | 3720 int idx; |
3721 int stack_idx; | |
3722 int text_start; | |
3723 int line_start; | |
3724 long line_size; | |
3725 int i; | |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3726 int ret = FAIL; |
18763
49b78d6465e5
patch 8.1.2371: FEAT_TEXT_PROP is a confusing name
Bram Moolenaar <Bram@vim.org>
parents:
18498
diff
changeset
|
3727 #ifdef FEAT_PROP_POPUP |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3728 char_u *textprop_save = NULL; |
29682
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
3729 long textprop_len = 0; |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3730 #endif |
7 | 3731 |
3732 if (lowest_marked && lowest_marked > lnum) | |
3733 lowest_marked--; | |
3734 | |
3735 /* | |
3736 * If the file becomes empty the last line is replaced by an empty line. | |
3737 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3738 if (buf->b_ml.ml_line_count == 1) // file becomes empty |
7 | 3739 { |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3740 if ((flags & ML_DEL_MESSAGE) |
7 | 3741 #ifdef FEAT_NETBEANS_INTG |
3742 && !netbeansSuppressNoLines | |
3743 #endif | |
3744 ) | |
680 | 3745 set_keep_msg((char_u *)_(no_lines_msg), 0); |
3746 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3747 // FEAT_BYTEOFF already handled in there, don't worry 'bout it below |
7 | 3748 i = ml_replace((linenr_T)1, (char_u *)"", TRUE); |
3749 buf->b_ml.ml_flags |= ML_EMPTY; | |
3750 | |
3751 return i; | |
3752 } | |
3753 | |
3754 /* | |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3755 * Find the data block containing the line. |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3756 * This also fills the stack with the blocks from the root to the data block. |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3757 * This also releases any locked block.. |
7 | 3758 */ |
3759 mfp = buf->b_ml.ml_mfp; | |
3760 if (mfp == NULL) | |
3761 return FAIL; | |
3762 | |
3763 if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL) | |
3764 return FAIL; | |
3765 | |
3766 dp = (DATA_BL *)(hp->bh_data); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3767 // compute line count before the delete |
7 | 3768 count = (long)(buf->b_ml.ml_locked_high) |
3769 - (long)(buf->b_ml.ml_locked_low) + 2; | |
3770 idx = lnum - buf->b_ml.ml_locked_low; | |
3771 | |
3772 --buf->b_ml.ml_line_count; | |
3773 | |
3774 line_start = ((dp->db_index[idx]) & DB_INDEX_MASK); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3775 if (idx == 0) // first line in block, text at the end |
7 | 3776 line_size = dp->db_txt_end - line_start; |
3777 else | |
3778 line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start; | |
3779 | |
3780 #ifdef FEAT_NETBEANS_INTG | |
2210 | 3781 if (netbeans_active()) |
27426
41e0dcf38521
patch 8.2.4241: some type casts are redundant
Bram Moolenaar <Bram@vim.org>
parents:
27231
diff
changeset
|
3782 netbeans_removed(buf, lnum, 0, line_size); |
7 | 3783 #endif |
18763
49b78d6465e5
patch 8.1.2371: FEAT_TEXT_PROP is a confusing name
Bram Moolenaar <Bram@vim.org>
parents:
18498
diff
changeset
|
3784 #ifdef FEAT_PROP_POPUP |
29682
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
3785 // If there are text properties compute their byte length. |
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
3786 // if needed make a copy, so that we can update properties in preceding and |
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
3787 // following lines. |
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
3788 if (buf->b_has_textprop) |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3789 { |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3790 size_t textlen = STRLEN((char_u *)dp + line_start) + 1; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3791 |
29682
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
3792 textprop_len = line_size - (long)textlen; |
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
3793 if (!(flags & (ML_DEL_UNDO | ML_DEL_NOPROP)) && textprop_len > 0) |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3794 textprop_save = vim_memsave((char_u *)dp + line_start + textlen, |
29682
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
3795 textprop_len); |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3796 } |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3797 #endif |
7 | 3798 |
3799 /* | |
3800 * special case: If there is only one line in the data block it becomes empty. | |
3801 * Then we have to remove the entry, pointing to this data block, from the | |
3802 * pointer block. If this pointer block also becomes empty, we go up another | |
3803 * block, and so on, up to the root if necessary. | |
3804 * The line counts in the pointer blocks have already been adjusted by | |
3805 * ml_find_line(). | |
3806 */ | |
3807 if (count == 1) | |
3808 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3809 mf_free(mfp, hp); // free the data block |
7 | 3810 buf->b_ml.ml_locked = NULL; |
3811 | |
2823 | 3812 for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0; |
3813 --stack_idx) | |
7 | 3814 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3815 buf->b_ml.ml_stack_top = 0; // stack is invalid when failing |
7 | 3816 ip = &(buf->b_ml.ml_stack[stack_idx]); |
3817 idx = ip->ip_index; | |
3818 if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) | |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3819 goto theend; |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3820 pp = (PTR_BL *)(hp->bh_data); // must be pointer block |
7 | 3821 if (pp->pb_id != PTR_ID) |
3822 { | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
3823 iemsg(_(e_pointer_block_id_wrong_four)); |
7 | 3824 mf_put(mfp, hp, FALSE, FALSE); |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3825 goto theend; |
7 | 3826 } |
3827 count = --(pp->pb_count); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3828 if (count == 0) // the pointer block becomes empty! |
7 | 3829 mf_free(mfp, hp); |
3830 else | |
3831 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3832 if (count != idx) // move entries after the deleted one |
7 | 3833 mch_memmove(&pp->pb_pointer[idx], &pp->pb_pointer[idx + 1], |
3834 (size_t)(count - idx) * sizeof(PTR_EN)); | |
3835 mf_put(mfp, hp, TRUE, FALSE); | |
3836 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3837 buf->b_ml.ml_stack_top = stack_idx; // truncate stack |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3838 // fix line count for rest of blocks in the stack |
1167 | 3839 if (buf->b_ml.ml_locked_lineadd != 0) |
7 | 3840 { |
3841 ml_lineadd(buf, buf->b_ml.ml_locked_lineadd); | |
3842 buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high += | |
1167 | 3843 buf->b_ml.ml_locked_lineadd; |
7 | 3844 } |
3845 ++(buf->b_ml.ml_stack_top); | |
3846 | |
3847 break; | |
3848 } | |
3849 } | |
3850 CHECK(stack_idx < 0, _("deleted block 1?")); | |
3851 } | |
3852 else | |
3853 { | |
3854 /* | |
3855 * delete the text by moving the next lines forwards | |
3856 */ | |
3857 text_start = dp->db_txt_start; | |
3858 mch_memmove((char *)dp + text_start + line_size, | |
3859 (char *)dp + text_start, (size_t)(line_start - text_start)); | |
3860 | |
3861 /* | |
3862 * delete the index by moving the next indexes backwards | |
3863 * Adjust the indexes for the text movement. | |
3864 */ | |
3865 for (i = idx; i < count - 1; ++i) | |
3866 dp->db_index[i] = dp->db_index[i + 1] + line_size; | |
3867 | |
3868 dp->db_free += line_size + INDEX_SIZE; | |
3869 dp->db_txt_start += line_size; | |
3870 --(dp->db_line_count); | |
3871 | |
3872 /* | |
3873 * mark the block dirty and make sure it is in the file (for recovery) | |
3874 */ | |
3875 buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS); | |
3876 } | |
3877 | |
3878 #ifdef FEAT_BYTEOFF | |
25672
ab42c36d1a27
patch 8.2.3372: line2byte() value wrong when adding a text property
Bram Moolenaar <Bram@vim.org>
parents:
25638
diff
changeset
|
3879 ml_updatechunk(buf, lnum, line_size |
ab42c36d1a27
patch 8.2.3372: line2byte() value wrong when adding a text property
Bram Moolenaar <Bram@vim.org>
parents:
25638
diff
changeset
|
3880 # ifdef FEAT_PROP_POPUP |
29682
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
3881 - textprop_len |
25672
ab42c36d1a27
patch 8.2.3372: line2byte() value wrong when adding a text property
Bram Moolenaar <Bram@vim.org>
parents:
25638
diff
changeset
|
3882 # endif |
29682
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
3883 , ML_CHNK_DELLINE); |
7 | 3884 #endif |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3885 ret = OK; |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3886 |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3887 theend: |
18763
49b78d6465e5
patch 8.1.2371: FEAT_TEXT_PROP is a confusing name
Bram Moolenaar <Bram@vim.org>
parents:
18498
diff
changeset
|
3888 #ifdef FEAT_PROP_POPUP |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3889 if (textprop_save != NULL) |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3890 { |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3891 // Adjust text properties in the line above and below. |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3892 if (lnum > 1) |
25050
7ef7a211f6bf
patch 8.2.3062: internal error when adding several text properties
Bram Moolenaar <Bram@vim.org>
parents:
24990
diff
changeset
|
3893 adjust_text_props_for_delete(buf, lnum - 1, textprop_save, |
29682
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
3894 (int)textprop_len, TRUE); |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3895 if (lnum <= buf->b_ml.ml_line_count) |
25050
7ef7a211f6bf
patch 8.2.3062: internal error when adding several text properties
Bram Moolenaar <Bram@vim.org>
parents:
24990
diff
changeset
|
3896 adjust_text_props_for_delete(buf, lnum, textprop_save, |
29682
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
3897 (int)textprop_len, FALSE); |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3898 } |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3899 vim_free(textprop_save); |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3900 #endif |
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3901 return ret; |
7 | 3902 } |
3903 | |
3904 /* | |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3905 * Delete line "lnum" in the current buffer. |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3906 * When "message" is TRUE may give a "No lines in buffer" message. |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3907 * |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3908 * Check: The caller of this function should probably also call |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3909 * deleted_lines() after this. |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3910 * |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3911 * return FAIL for failure, OK otherwise |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3912 */ |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3913 int |
20599
d571231175b4
patch 8.2.0853: ml_delete() often called with FALSE argument
Bram Moolenaar <Bram@vim.org>
parents:
20583
diff
changeset
|
3914 ml_delete(linenr_T lnum) |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3915 { |
20599
d571231175b4
patch 8.2.0853: ml_delete() often called with FALSE argument
Bram Moolenaar <Bram@vim.org>
parents:
20583
diff
changeset
|
3916 return ml_delete_flags(lnum, 0); |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3917 } |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3918 |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3919 /* |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3920 * Like ml_delete() but using flags (see ml_delete_int()). |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3921 */ |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3922 int |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3923 ml_delete_flags(linenr_T lnum, int flags) |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3924 { |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3925 ml_flush_line(curbuf); |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3926 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3927 return FAIL; |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3928 |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3929 #ifdef FEAT_EVAL |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3930 // When inserting above recorded changes: flush the changes before changing |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3931 // the text. |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3932 may_invoke_listeners(curbuf, lnum, lnum + 1, -1); |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3933 #endif |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3934 |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3935 return ml_delete_int(curbuf, lnum, flags); |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3936 } |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3937 |
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
3938 /* |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3939 * set the DB_MARKED flag for line 'lnum' |
7 | 3940 */ |
3941 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
3942 ml_setmarked(linenr_T lnum) |
7 | 3943 { |
3944 bhdr_T *hp; | |
3945 DATA_BL *dp; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3946 // invalid line number |
7 | 3947 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count |
3948 || curbuf->b_ml.ml_mfp == NULL) | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3949 return; // give error message? |
7 | 3950 |
3951 if (lowest_marked == 0 || lowest_marked > lnum) | |
3952 lowest_marked = lnum; | |
3953 | |
3954 /* | |
3955 * find the data block containing the line | |
3956 * This also fills the stack with the blocks from the root to the data block | |
3957 * This also releases any locked block. | |
3958 */ | |
3959 if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3960 return; // give error message? |
7 | 3961 |
3962 dp = (DATA_BL *)(hp->bh_data); | |
3963 dp->db_index[lnum - curbuf->b_ml.ml_locked_low] |= DB_MARKED; | |
3964 curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY; | |
3965 } | |
3966 | |
3967 /* | |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
3968 * find the first line with its DB_MARKED flag set |
7 | 3969 */ |
3970 linenr_T | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
3971 ml_firstmarked(void) |
7 | 3972 { |
3973 bhdr_T *hp; | |
3974 DATA_BL *dp; | |
3975 linenr_T lnum; | |
3976 int i; | |
3977 | |
3978 if (curbuf->b_ml.ml_mfp == NULL) | |
3979 return (linenr_T) 0; | |
3980 | |
3981 /* | |
3982 * The search starts with lowest_marked line. This is the last line where | |
3983 * a mark was found, adjusted by inserting/deleting lines. | |
3984 */ | |
3985 for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; ) | |
3986 { | |
3987 /* | |
3988 * Find the data block containing the line. | |
3989 * This also fills the stack with the blocks from the root to the data | |
3990 * block This also releases any locked block. | |
3991 */ | |
3992 if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
3993 return (linenr_T)0; // give error message? |
7 | 3994 |
3995 dp = (DATA_BL *)(hp->bh_data); | |
3996 | |
3997 for (i = lnum - curbuf->b_ml.ml_locked_low; | |
3998 lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum) | |
3999 if ((dp->db_index[i]) & DB_MARKED) | |
4000 { | |
4001 (dp->db_index[i]) &= DB_INDEX_MASK; | |
4002 curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY; | |
4003 lowest_marked = lnum + 1; | |
4004 return lnum; | |
4005 } | |
4006 } | |
4007 | |
4008 return (linenr_T) 0; | |
4009 } | |
4010 | |
4011 /* | |
4012 * clear all DB_MARKED flags | |
4013 */ | |
4014 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4015 ml_clearmarked(void) |
7 | 4016 { |
4017 bhdr_T *hp; | |
4018 DATA_BL *dp; | |
4019 linenr_T lnum; | |
4020 int i; | |
4021 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4022 if (curbuf->b_ml.ml_mfp == NULL) // nothing to do |
7 | 4023 return; |
4024 | |
4025 /* | |
4026 * The search starts with line lowest_marked. | |
4027 */ | |
4028 for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; ) | |
4029 { | |
4030 /* | |
4031 * Find the data block containing the line. | |
4032 * This also fills the stack with the blocks from the root to the data | |
4033 * block and releases any locked block. | |
4034 */ | |
4035 if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL) | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4036 return; // give error message? |
7 | 4037 |
4038 dp = (DATA_BL *)(hp->bh_data); | |
4039 | |
4040 for (i = lnum - curbuf->b_ml.ml_locked_low; | |
4041 lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum) | |
4042 if ((dp->db_index[i]) & DB_MARKED) | |
4043 { | |
4044 (dp->db_index[i]) &= DB_INDEX_MASK; | |
4045 curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY; | |
4046 } | |
4047 } | |
4048 | |
4049 lowest_marked = 0; | |
4050 } | |
4051 | |
4052 /* | |
4053 * flush ml_line if necessary | |
4054 */ | |
4055 static void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4056 ml_flush_line(buf_T *buf) |
7 | 4057 { |
4058 bhdr_T *hp; | |
4059 DATA_BL *dp; | |
4060 linenr_T lnum; | |
4061 char_u *new_line; | |
4062 char_u *old_line; | |
4063 colnr_T new_len; | |
4064 int old_len; | |
4065 int extra; | |
4066 int idx; | |
4067 int start; | |
4068 int count; | |
4069 int i; | |
2075
903fcd726d90
updated for version 7.2.359
Bram Moolenaar <bram@zimbu.org>
parents:
2003
diff
changeset
|
4070 static int entered = FALSE; |
7 | 4071 |
4072 if (buf->b_ml.ml_line_lnum == 0 || buf->b_ml.ml_mfp == NULL) | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4073 return; // nothing to do |
7 | 4074 |
4075 if (buf->b_ml.ml_flags & ML_LINE_DIRTY) | |
4076 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4077 // This code doesn't work recursively, but Netbeans may call back here |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4078 // when obtaining the cursor position. |
2075
903fcd726d90
updated for version 7.2.359
Bram Moolenaar <bram@zimbu.org>
parents:
2003
diff
changeset
|
4079 if (entered) |
903fcd726d90
updated for version 7.2.359
Bram Moolenaar <bram@zimbu.org>
parents:
2003
diff
changeset
|
4080 return; |
903fcd726d90
updated for version 7.2.359
Bram Moolenaar <bram@zimbu.org>
parents:
2003
diff
changeset
|
4081 entered = TRUE; |
903fcd726d90
updated for version 7.2.359
Bram Moolenaar <bram@zimbu.org>
parents:
2003
diff
changeset
|
4082 |
7 | 4083 lnum = buf->b_ml.ml_line_lnum; |
4084 new_line = buf->b_ml.ml_line_ptr; | |
4085 | |
4086 hp = ml_find_line(buf, lnum, ML_FIND); | |
4087 if (hp == NULL) | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
4088 siemsg(_(e_cannot_find_line_nr), lnum); |
7 | 4089 else |
4090 { | |
4091 dp = (DATA_BL *)(hp->bh_data); | |
4092 idx = lnum - buf->b_ml.ml_locked_low; | |
4093 start = ((dp->db_index[idx]) & DB_INDEX_MASK); | |
4094 old_line = (char_u *)dp + start; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4095 if (idx == 0) // line is last in block |
7 | 4096 old_len = dp->db_txt_end - start; |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4097 else // text of previous line follows |
7 | 4098 old_len = (dp->db_index[idx - 1] & DB_INDEX_MASK) - start; |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
4099 new_len = buf->b_ml.ml_line_len; |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4100 extra = new_len - old_len; // negative if lines gets smaller |
7 | 4101 |
4102 /* | |
4103 * if new line fits in data block, replace directly | |
4104 */ | |
4105 if ((int)dp->db_free >= extra) | |
4106 { | |
25636
885fba352580
patch 8.2.3354: build failure with +byte_offset but without +textprop
Bram Moolenaar <Bram@vim.org>
parents:
25624
diff
changeset
|
4107 #if defined(FEAT_BYTEOFF) && defined(FEAT_PROP_POPUP) |
25624
0ef8ef1af478
patch 8.2.3348: line2byte() returns wrong value after adding textprop
Bram Moolenaar <Bram@vim.org>
parents:
25417
diff
changeset
|
4108 int old_prop_len = 0; |
28984
b3828315a0d9
patch 8.2.5014: byte offsets are wrong when using text properties
Bram Moolenaar <Bram@vim.org>
parents:
28877
diff
changeset
|
4109 if (buf->b_has_textprop) |
b3828315a0d9
patch 8.2.5014: byte offsets are wrong when using text properties
Bram Moolenaar <Bram@vim.org>
parents:
28877
diff
changeset
|
4110 old_prop_len = old_len - (int)STRLEN(old_line) - 1; |
25624
0ef8ef1af478
patch 8.2.3348: line2byte() returns wrong value after adding textprop
Bram Moolenaar <Bram@vim.org>
parents:
25417
diff
changeset
|
4111 #endif |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4112 // if the length changes and there are following lines |
7 | 4113 count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1; |
4114 if (extra != 0 && idx < count - 1) | |
4115 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4116 // move text of following lines |
7 | 4117 mch_memmove((char *)dp + dp->db_txt_start - extra, |
4118 (char *)dp + dp->db_txt_start, | |
4119 (size_t)(start - dp->db_txt_start)); | |
4120 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4121 // adjust pointers of this and following lines |
7 | 4122 for (i = idx + 1; i < count; ++i) |
4123 dp->db_index[i] -= extra; | |
4124 } | |
4125 dp->db_index[idx] -= extra; | |
4126 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4127 // adjust free space |
7 | 4128 dp->db_free -= extra; |
4129 dp->db_txt_start -= extra; | |
4130 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4131 // copy new line into the data block |
7 | 4132 mch_memmove(old_line - extra, new_line, (size_t)new_len); |
4133 buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS); | |
25636
885fba352580
patch 8.2.3354: build failure with +byte_offset but without +textprop
Bram Moolenaar <Bram@vim.org>
parents:
25624
diff
changeset
|
4134 #if defined(FEAT_BYTEOFF) && defined(FEAT_PROP_POPUP) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4135 // The else case is already covered by the insert and delete |
25624
0ef8ef1af478
patch 8.2.3348: line2byte() returns wrong value after adding textprop
Bram Moolenaar <Bram@vim.org>
parents:
25417
diff
changeset
|
4136 if (buf->b_has_textprop) |
0ef8ef1af478
patch 8.2.3348: line2byte() returns wrong value after adding textprop
Bram Moolenaar <Bram@vim.org>
parents:
25417
diff
changeset
|
4137 { |
0ef8ef1af478
patch 8.2.3348: line2byte() returns wrong value after adding textprop
Bram Moolenaar <Bram@vim.org>
parents:
25417
diff
changeset
|
4138 // Do not count the size of any text properties. |
0ef8ef1af478
patch 8.2.3348: line2byte() returns wrong value after adding textprop
Bram Moolenaar <Bram@vim.org>
parents:
25417
diff
changeset
|
4139 extra += old_prop_len; |
25638
960ff2a7d921
patch 8.2.3355: MS-Windows: compiler warning for 64-32 bit conversion
Bram Moolenaar <Bram@vim.org>
parents:
25636
diff
changeset
|
4140 extra -= new_len - (int)STRLEN(new_line) - 1; |
25624
0ef8ef1af478
patch 8.2.3348: line2byte() returns wrong value after adding textprop
Bram Moolenaar <Bram@vim.org>
parents:
25417
diff
changeset
|
4141 } |
0ef8ef1af478
patch 8.2.3348: line2byte() returns wrong value after adding textprop
Bram Moolenaar <Bram@vim.org>
parents:
25417
diff
changeset
|
4142 if (extra != 0) |
0ef8ef1af478
patch 8.2.3348: line2byte() returns wrong value after adding textprop
Bram Moolenaar <Bram@vim.org>
parents:
25417
diff
changeset
|
4143 ml_updatechunk(buf, lnum, (long)extra, ML_CHNK_UPDLINE); |
7 | 4144 #endif |
4145 } | |
4146 else | |
4147 { | |
4148 /* | |
4149 * Cannot do it in one data block: Delete and append. | |
4150 * Append first, because ml_delete_int() cannot delete the | |
4151 * last line in a buffer, which causes trouble for a buffer | |
4152 * that has only one line. | |
4153 * Don't forget to copy the mark! | |
4154 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4155 // How about handling errors??? |
20581
e529690f27bc
patch 8.2.0844: text properties crossing lines not handled correctly
Bram Moolenaar <Bram@vim.org>
parents:
19396
diff
changeset
|
4156 (void)ml_append_int(buf, lnum, new_line, new_len, |
24703
4bc0bda6857d
patch 8.2.2890: text property duplicated when data block splits
Bram Moolenaar <Bram@vim.org>
parents:
24093
diff
changeset
|
4157 ((dp->db_index[idx] & DB_MARKED) ? ML_APPEND_MARK : 0) |
4bc0bda6857d
patch 8.2.2890: text property duplicated when data block splits
Bram Moolenaar <Bram@vim.org>
parents:
24093
diff
changeset
|
4158 #ifdef FEAT_PROP_POPUP |
4bc0bda6857d
patch 8.2.2890: text property duplicated when data block splits
Bram Moolenaar <Bram@vim.org>
parents:
24093
diff
changeset
|
4159 | ML_APPEND_NOPROP |
4bc0bda6857d
patch 8.2.2890: text property duplicated when data block splits
Bram Moolenaar <Bram@vim.org>
parents:
24093
diff
changeset
|
4160 #endif |
4bc0bda6857d
patch 8.2.2890: text property duplicated when data block splits
Bram Moolenaar <Bram@vim.org>
parents:
24093
diff
changeset
|
4161 ); |
25050
7ef7a211f6bf
patch 8.2.3062: internal error when adding several text properties
Bram Moolenaar <Bram@vim.org>
parents:
24990
diff
changeset
|
4162 (void)ml_delete_int(buf, lnum, ML_DEL_NOPROP); |
7 | 4163 } |
4164 } | |
4165 vim_free(new_line); | |
2075
903fcd726d90
updated for version 7.2.359
Bram Moolenaar <bram@zimbu.org>
parents:
2003
diff
changeset
|
4166 |
903fcd726d90
updated for version 7.2.359
Bram Moolenaar <bram@zimbu.org>
parents:
2003
diff
changeset
|
4167 entered = FALSE; |
7 | 4168 } |
29340
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
4169 else if (buf->b_ml.ml_flags & ML_ALLOCATED) |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
4170 vim_free(buf->b_ml.ml_line_ptr); |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
4171 |
fba9e366ced4
patch 9.0.0013: reproducing memory access errors can be difficult
Bram Moolenaar <Bram@vim.org>
parents:
28984
diff
changeset
|
4172 buf->b_ml.ml_flags &= ~(ML_LINE_DIRTY | ML_ALLOCATED); |
7 | 4173 buf->b_ml.ml_line_lnum = 0; |
4174 } | |
4175 | |
4176 /* | |
4177 * create a new, empty, data block | |
4178 */ | |
4179 static bhdr_T * | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4180 ml_new_data(memfile_T *mfp, int negative, int page_count) |
7 | 4181 { |
4182 bhdr_T *hp; | |
4183 DATA_BL *dp; | |
4184 | |
4185 if ((hp = mf_new(mfp, negative, page_count)) == NULL) | |
4186 return NULL; | |
4187 | |
4188 dp = (DATA_BL *)(hp->bh_data); | |
4189 dp->db_id = DATA_ID; | |
4190 dp->db_txt_start = dp->db_txt_end = page_count * mfp->mf_page_size; | |
4191 dp->db_free = dp->db_txt_start - HEADER_SIZE; | |
4192 dp->db_line_count = 0; | |
4193 | |
4194 return hp; | |
4195 } | |
4196 | |
4197 /* | |
4198 * create a new, empty, pointer block | |
4199 */ | |
4200 static bhdr_T * | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4201 ml_new_ptr(memfile_T *mfp) |
7 | 4202 { |
4203 bhdr_T *hp; | |
4204 PTR_BL *pp; | |
4205 | |
4206 if ((hp = mf_new(mfp, FALSE, 1)) == NULL) | |
4207 return NULL; | |
4208 | |
4209 pp = (PTR_BL *)(hp->bh_data); | |
4210 pp->pb_id = PTR_ID; | |
4211 pp->pb_count = 0; | |
32290
9b0c304500cc
patch 9.0.1477: crash when recovering from corrupted swap file
Bram Moolenaar <Bram@vim.org>
parents:
31877
diff
changeset
|
4212 pp->pb_count_max = PB_COUNT_MAX(mfp); |
7 | 4213 |
4214 return hp; | |
4215 } | |
4216 | |
4217 /* | |
15292
ba6f0f1bb9d0
patch 8.1.0654: when deleting a line text property flags are not adjusted
Bram Moolenaar <Bram@vim.org>
parents:
15269
diff
changeset
|
4218 * Lookup line 'lnum' in a memline. |
7 | 4219 * |
4220 * action: if ML_DELETE or ML_INSERT the line count is updated while searching | |
4221 * if ML_FLUSH only flush a locked block | |
4222 * if ML_FIND just find the line | |
4223 * | |
4224 * If the block was found it is locked and put in ml_locked. | |
4225 * The stack is updated to lead to the locked block. The ip_high field in | |
4226 * the stack is updated to reflect the last line in the block AFTER the | |
4227 * insert or delete, also if the pointer block has not been updated yet. But | |
1167 | 4228 * if ml_locked != NULL ml_locked_lineadd must be added to ip_high. |
7 | 4229 * |
4230 * return: NULL for failure, pointer to block header otherwise | |
4231 */ | |
4232 static bhdr_T * | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4233 ml_find_line(buf_T *buf, linenr_T lnum, int action) |
7 | 4234 { |
4235 DATA_BL *dp; | |
4236 PTR_BL *pp; | |
4237 infoptr_T *ip; | |
4238 bhdr_T *hp; | |
4239 memfile_T *mfp; | |
4240 linenr_T t; | |
4241 blocknr_T bnum, bnum2; | |
4242 int dirty; | |
4243 linenr_T low, high; | |
4244 int top; | |
4245 int page_count; | |
4246 int idx; | |
4247 | |
4248 mfp = buf->b_ml.ml_mfp; | |
4249 | |
4250 /* | |
4251 * If there is a locked block check if the wanted line is in it. | |
4252 * If not, flush and release the locked block. | |
4253 * Don't do this for ML_INSERT_SAME, because the stack need to be updated. | |
4254 * Don't do this for ML_FLUSH, because we want to flush the locked block. | |
1066 | 4255 * Don't do this when 'swapfile' is reset, we want to load all the blocks. |
7 | 4256 */ |
4257 if (buf->b_ml.ml_locked) | |
4258 { | |
1066 | 4259 if (ML_SIMPLE(action) |
4260 && buf->b_ml.ml_locked_low <= lnum | |
4261 && buf->b_ml.ml_locked_high >= lnum | |
4262 && !mf_dont_release) | |
7 | 4263 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4264 // remember to update pointer blocks and stack later |
7 | 4265 if (action == ML_INSERT) |
4266 { | |
4267 ++(buf->b_ml.ml_locked_lineadd); | |
4268 ++(buf->b_ml.ml_locked_high); | |
4269 } | |
4270 else if (action == ML_DELETE) | |
4271 { | |
4272 --(buf->b_ml.ml_locked_lineadd); | |
4273 --(buf->b_ml.ml_locked_high); | |
4274 } | |
4275 return (buf->b_ml.ml_locked); | |
4276 } | |
4277 | |
4278 mf_put(mfp, buf->b_ml.ml_locked, buf->b_ml.ml_flags & ML_LOCKED_DIRTY, | |
4279 buf->b_ml.ml_flags & ML_LOCKED_POS); | |
4280 buf->b_ml.ml_locked = NULL; | |
4281 | |
1167 | 4282 /* |
4283 * If lines have been added or deleted in the locked block, need to | |
4284 * update the line count in pointer blocks. | |
4285 */ | |
4286 if (buf->b_ml.ml_locked_lineadd != 0) | |
7 | 4287 ml_lineadd(buf, buf->b_ml.ml_locked_lineadd); |
4288 } | |
4289 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4290 if (action == ML_FLUSH) // nothing else to do |
7 | 4291 return NULL; |
4292 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4293 bnum = 1; // start at the root of the tree |
7 | 4294 page_count = 1; |
4295 low = 1; | |
4296 high = buf->b_ml.ml_line_count; | |
4297 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4298 if (action == ML_FIND) // first try stack entries |
7 | 4299 { |
4300 for (top = buf->b_ml.ml_stack_top - 1; top >= 0; --top) | |
4301 { | |
4302 ip = &(buf->b_ml.ml_stack[top]); | |
4303 if (ip->ip_low <= lnum && ip->ip_high >= lnum) | |
4304 { | |
4305 bnum = ip->ip_bnum; | |
4306 low = ip->ip_low; | |
4307 high = ip->ip_high; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4308 buf->b_ml.ml_stack_top = top; // truncate stack at prev entry |
7 | 4309 break; |
4310 } | |
4311 } | |
4312 if (top < 0) | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4313 buf->b_ml.ml_stack_top = 0; // not found, start at the root |
7 | 4314 } |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4315 else // ML_DELETE or ML_INSERT |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4316 buf->b_ml.ml_stack_top = 0; // start at the root |
7 | 4317 |
4318 /* | |
4319 * search downwards in the tree until a data block is found | |
4320 */ | |
4321 for (;;) | |
4322 { | |
4323 if ((hp = mf_get(mfp, bnum, page_count)) == NULL) | |
4324 goto error_noblock; | |
4325 | |
4326 /* | |
4327 * update high for insert/delete | |
4328 */ | |
4329 if (action == ML_INSERT) | |
4330 ++high; | |
4331 else if (action == ML_DELETE) | |
4332 --high; | |
4333 | |
4334 dp = (DATA_BL *)(hp->bh_data); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4335 if (dp->db_id == DATA_ID) // data block |
7 | 4336 { |
4337 buf->b_ml.ml_locked = hp; | |
4338 buf->b_ml.ml_locked_low = low; | |
4339 buf->b_ml.ml_locked_high = high; | |
4340 buf->b_ml.ml_locked_lineadd = 0; | |
4341 buf->b_ml.ml_flags &= ~(ML_LOCKED_DIRTY | ML_LOCKED_POS); | |
4342 return hp; | |
4343 } | |
4344 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4345 pp = (PTR_BL *)(dp); // must be pointer block |
7 | 4346 if (pp->pb_id != PTR_ID) |
4347 { | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
4348 iemsg(_(e_pointer_block_id_wrong)); |
7 | 4349 goto error_block; |
4350 } | |
4351 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4352 if ((top = ml_add_stack(buf)) < 0) // add new entry to stack |
7 | 4353 goto error_block; |
4354 ip = &(buf->b_ml.ml_stack[top]); | |
4355 ip->ip_bnum = bnum; | |
4356 ip->ip_low = low; | |
4357 ip->ip_high = high; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4358 ip->ip_index = -1; // index not known yet |
7 | 4359 |
4360 dirty = FALSE; | |
4361 for (idx = 0; idx < (int)pp->pb_count; ++idx) | |
4362 { | |
4363 t = pp->pb_pointer[idx].pe_line_count; | |
4364 CHECK(t == 0, _("pe_line_count is zero")); | |
4365 if ((low += t) > lnum) | |
4366 { | |
4367 ip->ip_index = idx; | |
4368 bnum = pp->pb_pointer[idx].pe_bnum; | |
4369 page_count = pp->pb_pointer[idx].pe_page_count; | |
4370 high = low - 1; | |
4371 low -= t; | |
4372 | |
4373 /* | |
4374 * a negative block number may have been changed | |
4375 */ | |
4376 if (bnum < 0) | |
4377 { | |
4378 bnum2 = mf_trans_del(mfp, bnum); | |
4379 if (bnum != bnum2) | |
4380 { | |
4381 bnum = bnum2; | |
4382 pp->pb_pointer[idx].pe_bnum = bnum; | |
4383 dirty = TRUE; | |
4384 } | |
4385 } | |
4386 | |
4387 break; | |
4388 } | |
4389 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4390 if (idx >= (int)pp->pb_count) // past the end: something wrong! |
7 | 4391 { |
4392 if (lnum > buf->b_ml.ml_line_count) | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
4393 siemsg(_(e_line_number_out_of_range_nr_past_the_end), |
7 | 4394 lnum - buf->b_ml.ml_line_count); |
4395 | |
4396 else | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
4397 siemsg(_(e_line_count_wrong_in_block_nr), bnum); |
7 | 4398 goto error_block; |
4399 } | |
4400 if (action == ML_DELETE) | |
4401 { | |
4402 pp->pb_pointer[idx].pe_line_count--; | |
4403 dirty = TRUE; | |
4404 } | |
4405 else if (action == ML_INSERT) | |
4406 { | |
4407 pp->pb_pointer[idx].pe_line_count++; | |
4408 dirty = TRUE; | |
4409 } | |
4410 mf_put(mfp, hp, dirty, FALSE); | |
4411 } | |
4412 | |
4413 error_block: | |
4414 mf_put(mfp, hp, FALSE, FALSE); | |
4415 error_noblock: | |
2267 | 4416 /* |
4417 * If action is ML_DELETE or ML_INSERT we have to correct the tree for | |
4418 * the incremented/decremented line counts, because there won't be a line | |
4419 * inserted/deleted after all. | |
4420 */ | |
7 | 4421 if (action == ML_DELETE) |
4422 ml_lineadd(buf, 1); | |
4423 else if (action == ML_INSERT) | |
4424 ml_lineadd(buf, -1); | |
4425 buf->b_ml.ml_stack_top = 0; | |
4426 return NULL; | |
4427 } | |
4428 | |
4429 /* | |
4430 * add an entry to the info pointer stack | |
4431 * | |
4432 * return -1 for failure, number of the new entry otherwise | |
4433 */ | |
4434 static int | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4435 ml_add_stack(buf_T *buf) |
7 | 4436 { |
4437 int top; | |
4438 infoptr_T *newstack; | |
4439 | |
4440 top = buf->b_ml.ml_stack_top; | |
4441 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4442 // may have to increase the stack size |
7 | 4443 if (top == buf->b_ml.ml_stack_size) |
4444 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4445 CHECK(top > 0, _("Stack size increases")); // more than 5 levels??? |
7 | 4446 |
16825
ce04ebdf26b8
patch 8.1.1414: alloc() returning "char_u *" causes a lot of type casts
Bram Moolenaar <Bram@vim.org>
parents:
16786
diff
changeset
|
4447 newstack = ALLOC_MULT(infoptr_T, buf->b_ml.ml_stack_size + STACK_INCR); |
7 | 4448 if (newstack == NULL) |
4449 return -1; | |
6989 | 4450 if (top > 0) |
4451 mch_memmove(newstack, buf->b_ml.ml_stack, | |
1624 | 4452 (size_t)top * sizeof(infoptr_T)); |
7 | 4453 vim_free(buf->b_ml.ml_stack); |
4454 buf->b_ml.ml_stack = newstack; | |
4455 buf->b_ml.ml_stack_size += STACK_INCR; | |
4456 } | |
4457 | |
4458 buf->b_ml.ml_stack_top++; | |
4459 return top; | |
4460 } | |
4461 | |
4462 /* | |
4463 * Update the pointer blocks on the stack for inserted/deleted lines. | |
4464 * The stack itself is also updated. | |
4465 * | |
4466 * When a insert/delete line action fails, the line is not inserted/deleted, | |
4467 * but the pointer blocks have already been updated. That is fixed here by | |
4468 * walking through the stack. | |
4469 * | |
4470 * Count is the number of lines added, negative if lines have been deleted. | |
4471 */ | |
4472 static void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4473 ml_lineadd(buf_T *buf, int count) |
7 | 4474 { |
4475 int idx; | |
4476 infoptr_T *ip; | |
4477 PTR_BL *pp; | |
4478 memfile_T *mfp = buf->b_ml.ml_mfp; | |
4479 bhdr_T *hp; | |
4480 | |
4481 for (idx = buf->b_ml.ml_stack_top - 1; idx >= 0; --idx) | |
4482 { | |
4483 ip = &(buf->b_ml.ml_stack[idx]); | |
4484 if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) | |
4485 break; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4486 pp = (PTR_BL *)(hp->bh_data); // must be pointer block |
7 | 4487 if (pp->pb_id != PTR_ID) |
4488 { | |
4489 mf_put(mfp, hp, FALSE, FALSE); | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
4490 iemsg(_(e_pointer_block_id_wrong_two)); |
7 | 4491 break; |
4492 } | |
4493 pp->pb_pointer[ip->ip_index].pe_line_count += count; | |
4494 ip->ip_high += count; | |
4495 mf_put(mfp, hp, TRUE, FALSE); | |
4496 } | |
4497 } | |
4498 | |
2214
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4499 #if defined(HAVE_READLINK) || defined(PROTO) |
594 | 4500 /* |
4501 * Resolve a symlink in the last component of a file name. | |
4502 * Note that f_resolve() does it for every part of the path, we don't do that | |
4503 * here. | |
4504 * If it worked returns OK and the resolved link in "buf[MAXPATHL]". | |
4505 * Otherwise returns FAIL. | |
4506 */ | |
2214
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4507 int |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4508 resolve_symlink(char_u *fname, char_u *buf) |
594 | 4509 { |
4510 char_u tmp[MAXPATHL]; | |
4511 int ret; | |
4512 int depth = 0; | |
4513 | |
4514 if (fname == NULL) | |
4515 return FAIL; | |
4516 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4517 // Put the result so far in tmp[], starting with the original name. |
594 | 4518 vim_strncpy(tmp, fname, MAXPATHL - 1); |
4519 | |
4520 for (;;) | |
4521 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4522 // Limit symlink depth to 100, catch recursive loops. |
594 | 4523 if (++depth == 100) |
4524 { | |
26958
d92e0d85923f
patch 8.2.4008: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26909
diff
changeset
|
4525 semsg(_(e_symlink_loop_for_str), fname); |
594 | 4526 return FAIL; |
4527 } | |
4528 | |
4529 ret = readlink((char *)tmp, (char *)buf, MAXPATHL - 1); | |
4530 if (ret <= 0) | |
4531 { | |
619 | 4532 if (errno == EINVAL || errno == ENOENT) |
594 | 4533 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4534 // Found non-symlink or not existing file, stop here. |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4535 // When at the first level use the unmodified name, skip the |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4536 // call to vim_FullName(). |
594 | 4537 if (depth == 1) |
4538 return FAIL; | |
4539 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4540 // Use the resolved name in tmp[]. |
594 | 4541 break; |
4542 } | |
4543 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4544 // There must be some error reading links, use original name. |
594 | 4545 return FAIL; |
4546 } | |
4547 buf[ret] = NUL; | |
4548 | |
4549 /* | |
4550 * Check whether the symlink is relative or absolute. | |
4551 * If it's relative, build a new path based on the directory | |
4552 * portion of the filename (if any) and the path the symlink | |
4553 * points to. | |
4554 */ | |
4555 if (mch_isFullName(buf)) | |
4556 STRCPY(tmp, buf); | |
4557 else | |
4558 { | |
4559 char_u *tail; | |
4560 | |
4561 tail = gettail(tmp); | |
4562 if (STRLEN(tail) + STRLEN(buf) >= MAXPATHL) | |
4563 return FAIL; | |
4564 STRCPY(tail, buf); | |
4565 } | |
4566 } | |
4567 | |
4568 /* | |
4569 * Try to resolve the full name of the file so that the swapfile name will | |
4570 * be consistent even when opening a relative symlink from different | |
4571 * working directories. | |
4572 */ | |
4573 return vim_FullName(tmp, buf, MAXPATHL, TRUE); | |
4574 } | |
4575 #endif | |
4576 | |
7 | 4577 /* |
460 | 4578 * Make swap file name out of the file name and a directory name. |
4579 * Returns pointer to allocated memory or NULL. | |
7 | 4580 */ |
460 | 4581 char_u * |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4582 makeswapname( |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4583 char_u *fname, |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4584 char_u *ffname UNUSED, |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4585 buf_T *buf, |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4586 char_u *dir_name) |
7 | 4587 { |
4588 char_u *r, *s; | |
2145
de0e7ca61893
updated for version 7.2.427
Bram Moolenaar <bram@zimbu.org>
parents:
2108
diff
changeset
|
4589 char_u *fname_res = fname; |
594 | 4590 #ifdef HAVE_READLINK |
4591 char_u fname_buf[MAXPATHL]; | |
21337
647897e6df9e
patch 8.2.1219: symlink not followed if dirname ends in //
Bram Moolenaar <Bram@vim.org>
parents:
20830
diff
changeset
|
4592 |
647897e6df9e
patch 8.2.1219: symlink not followed if dirname ends in //
Bram Moolenaar <Bram@vim.org>
parents:
20830
diff
changeset
|
4593 // Expand symlink in the file name, so that we put the swap file with the |
647897e6df9e
patch 8.2.1219: symlink not followed if dirname ends in //
Bram Moolenaar <Bram@vim.org>
parents:
20830
diff
changeset
|
4594 // actual file instead of with the symlink. |
647897e6df9e
patch 8.2.1219: symlink not followed if dirname ends in //
Bram Moolenaar <Bram@vim.org>
parents:
20830
diff
changeset
|
4595 if (resolve_symlink(fname, fname_buf) == OK) |
647897e6df9e
patch 8.2.1219: symlink not followed if dirname ends in //
Bram Moolenaar <Bram@vim.org>
parents:
20830
diff
changeset
|
4596 fname_res = fname_buf; |
594 | 4597 #endif |
7 | 4598 |
15868
7fad90423bd2
patch 8.1.0941: macros for MS-Windows are inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15636
diff
changeset
|
4599 #if defined(UNIX) || defined(MSWIN) // Need _very_ long file names |
10996
2f041b367cd9
patch 8.0.0387: compiler warnings
Christian Brabandt <cb@256bit.org>
parents:
10952
diff
changeset
|
4600 int len = (int)STRLEN(dir_name); |
10896
d513b653f5d0
patch 8.0.0337: invalid memory access in :recover command
Christian Brabandt <cb@256bit.org>
parents:
10889
diff
changeset
|
4601 |
d513b653f5d0
patch 8.0.0337: invalid memory access in :recover command
Christian Brabandt <cb@256bit.org>
parents:
10889
diff
changeset
|
4602 s = dir_name + len; |
d513b653f5d0
patch 8.0.0337: invalid memory access in :recover command
Christian Brabandt <cb@256bit.org>
parents:
10889
diff
changeset
|
4603 if (after_pathsep(dir_name, s) && len > 1 && s[-1] == s[-2]) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4604 { // Ends with '//', Use Full path |
7 | 4605 r = NULL; |
21337
647897e6df9e
patch 8.2.1219: symlink not followed if dirname ends in //
Bram Moolenaar <Bram@vim.org>
parents:
20830
diff
changeset
|
4606 if ((s = make_percent_swname(dir_name, fname_res)) != NULL) |
7 | 4607 { |
4608 r = modname(s, (char_u *)".swp", FALSE); | |
4609 vim_free(s); | |
4610 } | |
4611 return r; | |
4612 } | |
4613 #endif | |
4614 | |
4615 r = buf_modname( | |
4616 (buf->b_p_sn || buf->b_shortname), | |
594 | 4617 fname_res, |
7 | 4618 (char_u *) |
2823 | 4619 #if defined(VMS) |
7 | 4620 "_swp", |
4621 #else | |
4622 ".swp", | |
4623 #endif | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4624 // Prepend a '.' to the swap file name for the current directory. |
8212
05b88224cea1
commit https://github.com/vim/vim/commit/48e330aff911be1c798c88a973af6437a8141fce
Christian Brabandt <cb@256bit.org>
parents:
7961
diff
changeset
|
4625 dir_name[0] == '.' && dir_name[1] == NUL); |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4626 if (r == NULL) // out of memory |
7 | 4627 return NULL; |
4628 | |
4629 s = get_file_in_dir(r, dir_name); | |
4630 vim_free(r); | |
4631 return s; | |
4632 } | |
4633 | |
4634 /* | |
4635 * Get file name to use for swap file or backup file. | |
4636 * Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir' | |
4637 * option "dname". | |
4638 * - If "dname" is ".", return "fname" (swap file in dir of file). | |
4639 * - If "dname" starts with "./", insert "dname" in "fname" (swap file | |
4640 * relative to dir of file). | |
4641 * - Otherwise, prepend "dname" to the tail of "fname" (swap file in specific | |
4642 * dir). | |
4643 * | |
4644 * The return value is an allocated string and can be NULL. | |
4645 */ | |
4646 char_u * | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4647 get_file_in_dir( |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4648 char_u *fname, |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4649 char_u *dname) // don't use "dirname", it is a global for Alpha |
7 | 4650 { |
4651 char_u *t; | |
4652 char_u *tail; | |
4653 char_u *retval; | |
4654 int save_char; | |
4655 | |
4656 tail = gettail(fname); | |
4657 | |
4658 if (dname[0] == '.' && dname[1] == NUL) | |
4659 retval = vim_strsave(fname); | |
4660 else if (dname[0] == '.' && vim_ispathsep(dname[1])) | |
4661 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4662 if (tail == fname) // no path before file name |
7 | 4663 retval = concat_fnames(dname + 2, tail, TRUE); |
4664 else | |
4665 { | |
4666 save_char = *tail; | |
4667 *tail = NUL; | |
4668 t = concat_fnames(fname, dname + 2, TRUE); | |
4669 *tail = save_char; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4670 if (t == NULL) // out of memory |
7 | 4671 retval = NULL; |
4672 else | |
4673 { | |
4674 retval = concat_fnames(t, tail, TRUE); | |
4675 vim_free(t); | |
4676 } | |
4677 } | |
4678 } | |
4679 else | |
4680 retval = concat_fnames(dname, tail, TRUE); | |
4681 | |
15868
7fad90423bd2
patch 8.1.0941: macros for MS-Windows are inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15636
diff
changeset
|
4682 #ifdef MSWIN |
5432 | 4683 if (retval != NULL) |
11127
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
10996
diff
changeset
|
4684 for (t = gettail(retval); *t != NUL; MB_PTR_ADV(t)) |
5432 | 4685 if (*t == ':') |
4686 *t = '%'; | |
4687 #endif | |
4688 | |
7 | 4689 return retval; |
4690 } | |
4691 | |
580 | 4692 /* |
4693 * Print the ATTENTION message: info about an existing swap file. | |
4694 */ | |
4695 static void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4696 attention_message( |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4697 buf_T *buf, // buffer being edited |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4698 char_u *fname) // swap file name |
580 | 4699 { |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
4700 stat_T st; |
16621
7ad3fc329e08
patch 8.1.1313: warnings for using localtime() and ctime()
Bram Moolenaar <Bram@vim.org>
parents:
16455
diff
changeset
|
4701 time_t swap_mtime; |
580 | 4702 |
4703 ++no_wait_return; | |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
4704 (void)emsg(_(e_attention)); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
4705 msg_puts(_("\nFound a swap file by the name \"")); |
580 | 4706 msg_home_replace(fname); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
4707 msg_puts("\"\n"); |
16621
7ad3fc329e08
patch 8.1.1313: warnings for using localtime() and ctime()
Bram Moolenaar <Bram@vim.org>
parents:
16455
diff
changeset
|
4708 swap_mtime = swapfile_info(fname); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
4709 msg_puts(_("While opening file \"")); |
580 | 4710 msg_outtrans(buf->b_fname); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
4711 msg_puts("\"\n"); |
14923
95400980f7c9
patch 8.1.0473: user doesn't notice file does not exist when swap file does
Bram Moolenaar <Bram@vim.org>
parents:
14909
diff
changeset
|
4712 if (mch_stat((char *)buf->b_fname, &st) == -1) |
95400980f7c9
patch 8.1.0473: user doesn't notice file does not exist when swap file does
Bram Moolenaar <Bram@vim.org>
parents:
14909
diff
changeset
|
4713 { |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
4714 msg_puts(_(" CANNOT BE FOUND")); |
14923
95400980f7c9
patch 8.1.0473: user doesn't notice file does not exist when swap file does
Bram Moolenaar <Bram@vim.org>
parents:
14909
diff
changeset
|
4715 } |
95400980f7c9
patch 8.1.0473: user doesn't notice file does not exist when swap file does
Bram Moolenaar <Bram@vim.org>
parents:
14909
diff
changeset
|
4716 else |
580 | 4717 { |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
4718 msg_puts(_(" dated: ")); |
16621
7ad3fc329e08
patch 8.1.1313: warnings for using localtime() and ctime()
Bram Moolenaar <Bram@vim.org>
parents:
16455
diff
changeset
|
4719 msg_puts(get_ctime(st.st_mtime, TRUE)); |
7ad3fc329e08
patch 8.1.1313: warnings for using localtime() and ctime()
Bram Moolenaar <Bram@vim.org>
parents:
16455
diff
changeset
|
4720 if (swap_mtime != 0 && st.st_mtime > swap_mtime) |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
4721 msg_puts(_(" NEWER than swap file!\n")); |
580 | 4722 } |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4723 // Some of these messages are long to allow translation to |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4724 // other languages. |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
4725 msg_puts(_("\n(1) Another program may be editing the same file. If this is the case,\n be careful not to end up with two different instances of the same\n file when making changes. Quit, or continue with caution.\n")); |
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
4726 msg_puts(_("(2) An edit session for this file crashed.\n")); |
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
4727 msg_puts(_(" If this is the case, use \":recover\" or \"vim -r ")); |
580 | 4728 msg_outtrans(buf->b_fname); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
4729 msg_puts(_("\"\n to recover the changes (see \":help recovery\").\n")); |
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
4730 msg_puts(_(" If you did this already, delete the swap file \"")); |
580 | 4731 msg_outtrans(fname); |
15543
dd725a8ab112
patch 8.1.0779: argument for message functions is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15470
diff
changeset
|
4732 msg_puts(_("\"\n to avoid this message.\n")); |
580 | 4733 cmdline_row = msg_row; |
4734 --no_wait_return; | |
4735 } | |
4736 | |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4737 typedef enum { |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4738 SEA_CHOICE_NONE = 0, |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4739 SEA_CHOICE_READONLY = 1, |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4740 SEA_CHOICE_EDIT = 2, |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4741 SEA_CHOICE_RECOVER = 3, |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4742 SEA_CHOICE_DELETE = 4, |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4743 SEA_CHOICE_QUIT = 5, |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4744 SEA_CHOICE_ABORT = 6 |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4745 } sea_choice_T; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4746 |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
4747 #if defined(FEAT_EVAL) |
580 | 4748 /* |
4749 * Trigger the SwapExists autocommands. | |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4750 * Returns a value for equivalent to do_dialog(). |
580 | 4751 */ |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4752 static sea_choice_T |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4753 do_swapexists(buf_T *buf, char_u *fname) |
580 | 4754 { |
4755 set_vim_var_string(VV_SWAPNAME, fname, -1); | |
4756 set_vim_var_string(VV_SWAPCHOICE, NULL, -1); | |
4757 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4758 // Trigger SwapExists autocommands with <afile> set to the file being |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4759 // edited. Disallow changing directory here. |
1856 | 4760 ++allbuf_lock; |
580 | 4761 apply_autocmds(EVENT_SWAPEXISTS, buf->b_fname, NULL, FALSE, NULL); |
1856 | 4762 --allbuf_lock; |
580 | 4763 |
4764 set_vim_var_string(VV_SWAPNAME, NULL, -1); | |
4765 | |
4766 switch (*get_vim_var_str(VV_SWAPCHOICE)) | |
4767 { | |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4768 case 'o': return SEA_CHOICE_READONLY; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4769 case 'e': return SEA_CHOICE_EDIT; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4770 case 'r': return SEA_CHOICE_RECOVER; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4771 case 'd': return SEA_CHOICE_DELETE; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4772 case 'q': return SEA_CHOICE_QUIT; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4773 case 'a': return SEA_CHOICE_ABORT; |
580 | 4774 } |
4775 | |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
4776 return SEA_CHOICE_NONE; |
580 | 4777 } |
4778 #endif | |
4779 | |
7 | 4780 /* |
4781 * Find out what name to use for the swap file for buffer 'buf'. | |
4782 * | |
4783 * Several names are tried to find one that does not exist | |
460 | 4784 * Returns the name in allocated memory or NULL. |
3158 | 4785 * When out of memory "dirp" is set to NULL. |
7 | 4786 * |
4787 * Note: If BASENAMELEN is not correct, you will get error messages for | |
2214
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4788 * not being able to open the swap or undo file |
1856 | 4789 * Note: May trigger SwapExists autocmd, pointers may change! |
7 | 4790 */ |
4791 static char_u * | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4792 findswapname( |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
4793 buf_T *buf, |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4794 char_u **dirp, // pointer to list of directories |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4795 char_u *old_fname) // don't give warning for this file name |
7 | 4796 { |
4797 char_u *fname; | |
4798 int n; | |
4799 char_u *dir_name; | |
4800 #ifdef AMIGA | |
4801 BPTR fh; | |
4802 #endif | |
4803 int r; | |
5432 | 4804 char_u *buf_fname = buf->b_fname; |
7 | 4805 |
8212
05b88224cea1
commit https://github.com/vim/vim/commit/48e330aff911be1c798c88a973af6437a8141fce
Christian Brabandt <cb@256bit.org>
parents:
7961
diff
changeset
|
4806 #if !defined(UNIX) |
7 | 4807 # define CREATE_DUMMY_FILE |
4808 FILE *dummyfd = NULL; | |
4809 | |
15868
7fad90423bd2
patch 8.1.0941: macros for MS-Windows are inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15636
diff
changeset
|
4810 # ifdef MSWIN |
5432 | 4811 if (buf_fname != NULL && !mch_isFullName(buf_fname) |
4812 && vim_strchr(gettail(buf_fname), ':')) | |
4813 { | |
4814 char_u *t; | |
4815 | |
4816 buf_fname = vim_strsave(buf_fname); | |
4817 if (buf_fname == NULL) | |
4818 buf_fname = buf->b_fname; | |
4819 else | |
11127
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
10996
diff
changeset
|
4820 for (t = gettail(buf_fname); *t != NUL; MB_PTR_ADV(t)) |
5432 | 4821 if (*t == ':') |
4822 *t = '%'; | |
4823 } | |
4824 # endif | |
4825 | |
2214
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4826 /* |
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4827 * If we start editing a new file, e.g. "test.doc", which resides on an |
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4828 * MSDOS compatible filesystem, it is possible that the file |
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4829 * "test.doc.swp" which we create will be exactly the same file. To avoid |
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4830 * this problem we temporarily create "test.doc". Don't do this when the |
26771
fc859aea8cec
patch 8.2.3914: various spelling mistakes in comments
Bram Moolenaar <Bram@vim.org>
parents:
26286
diff
changeset
|
4831 * check below for an 8.3 file name is used. |
2214
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4832 */ |
5432 | 4833 if (!(buf->b_p_sn || buf->b_shortname) && buf_fname != NULL |
4834 && mch_getperm(buf_fname) < 0) | |
4835 dummyfd = mch_fopen((char *)buf_fname, "w"); | |
7 | 4836 #endif |
4837 | |
2214
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4838 /* |
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4839 * Isolate a directory name from *dirp and put it in dir_name. |
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4840 * First allocate some memory to put the directory name in. |
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4841 */ |
16764
ef00b6bc186b
patch 8.1.1384: using "int" for alloc() often results in compiler warnings
Bram Moolenaar <Bram@vim.org>
parents:
16738
diff
changeset
|
4842 dir_name = alloc(STRLEN(*dirp) + 1); |
3158 | 4843 if (dir_name == NULL) |
4844 *dirp = NULL; | |
4845 else | |
7 | 4846 (void)copy_option_part(dirp, dir_name, 31000, ","); |
4847 | |
2214
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4848 /* |
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4849 * we try different names until we find one that does not exist yet |
f8222d1f9a73
Included patch for persistent undo. Lots of changes and added test.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4850 */ |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4851 if (dir_name == NULL) // out of memory |
7 | 4852 fname = NULL; |
4853 else | |
5432 | 4854 fname = makeswapname(buf_fname, buf->b_ffname, buf, dir_name); |
7 | 4855 |
4856 for (;;) | |
4857 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4858 if (fname == NULL) // must be out of memory |
7 | 4859 break; |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4860 if ((n = (int)STRLEN(fname)) == 0) // safety check |
7 | 4861 { |
13244
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
12975
diff
changeset
|
4862 VIM_CLEAR(fname); |
7 | 4863 break; |
4864 } | |
8212
05b88224cea1
commit https://github.com/vim/vim/commit/48e330aff911be1c798c88a973af6437a8141fce
Christian Brabandt <cb@256bit.org>
parents:
7961
diff
changeset
|
4865 #if defined(UNIX) |
7 | 4866 /* |
4867 * Some systems have a MS-DOS compatible filesystem that use 8.3 character | |
4868 * file names. If this is the first try and the swap file name does not fit in | |
4869 * 8.3, detect if this is the case, set shortname and try again. | |
4870 */ | |
4871 if (fname[n - 2] == 'w' && fname[n - 1] == 'p' | |
4872 && !(buf->b_p_sn || buf->b_shortname)) | |
4873 { | |
4874 char_u *tail; | |
4875 char_u *fname2; | |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
4876 stat_T s1, s2; |
7 | 4877 int f1, f2; |
4878 int created1 = FALSE, created2 = FALSE; | |
4879 int same = FALSE; | |
4880 | |
4881 /* | |
4882 * Check if swapfile name does not fit in 8.3: | |
4883 * It either contains two dots, is longer than 8 chars, or starts | |
4884 * with a dot. | |
4885 */ | |
5432 | 4886 tail = gettail(buf_fname); |
7 | 4887 if ( vim_strchr(tail, '.') != NULL |
4888 || STRLEN(tail) > (size_t)8 | |
4889 || *gettail(fname) == '.') | |
4890 { | |
4891 fname2 = alloc(n + 2); | |
4892 if (fname2 != NULL) | |
4893 { | |
4894 STRCPY(fname2, fname); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4895 // if fname == "xx.xx.swp", fname2 = "xx.xx.swx" |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4896 // if fname == ".xx.swp", fname2 = ".xx.swpx" |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4897 // if fname == "123456789.swp", fname2 = "12345678x.swp" |
7 | 4898 if (vim_strchr(tail, '.') != NULL) |
4899 fname2[n - 1] = 'x'; | |
4900 else if (*gettail(fname) == '.') | |
4901 { | |
4902 fname2[n] = 'x'; | |
4903 fname2[n + 1] = NUL; | |
4904 } | |
4905 else | |
4906 fname2[n - 5] += 1; | |
4907 /* | |
4908 * may need to create the files to be able to use mch_stat() | |
4909 */ | |
4910 f1 = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0); | |
4911 if (f1 < 0) | |
4912 { | |
4913 f1 = mch_open_rw((char *)fname, | |
4914 O_RDWR|O_CREAT|O_EXCL|O_EXTRA); | |
4915 created1 = TRUE; | |
4916 } | |
4917 if (f1 >= 0) | |
4918 { | |
4919 f2 = mch_open((char *)fname2, O_RDONLY | O_EXTRA, 0); | |
4920 if (f2 < 0) | |
4921 { | |
4922 f2 = mch_open_rw((char *)fname2, | |
4923 O_RDWR|O_CREAT|O_EXCL|O_EXTRA); | |
4924 created2 = TRUE; | |
4925 } | |
4926 if (f2 >= 0) | |
4927 { | |
4928 /* | |
4929 * Both files exist now. If mch_stat() returns the | |
4930 * same device and inode they are the same file. | |
4931 */ | |
4932 if (mch_fstat(f1, &s1) != -1 | |
4933 && mch_fstat(f2, &s2) != -1 | |
4934 && s1.st_dev == s2.st_dev | |
4935 && s1.st_ino == s2.st_ino) | |
4936 same = TRUE; | |
4937 close(f2); | |
4938 if (created2) | |
4939 mch_remove(fname2); | |
4940 } | |
4941 close(f1); | |
4942 if (created1) | |
4943 mch_remove(fname); | |
4944 } | |
4945 vim_free(fname2); | |
4946 if (same) | |
4947 { | |
4948 buf->b_shortname = TRUE; | |
4949 vim_free(fname); | |
5432 | 4950 fname = makeswapname(buf_fname, buf->b_ffname, |
460 | 4951 buf, dir_name); |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4952 continue; // try again with b_shortname set |
7 | 4953 } |
4954 } | |
4955 } | |
4956 } | |
4957 #endif | |
4958 /* | |
4959 * check if the swapfile already exists | |
4960 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4961 if (mch_getperm(fname) < 0) // it does not exist |
7 | 4962 { |
4963 #ifdef HAVE_LSTAT | |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
4964 stat_T sb; |
7 | 4965 |
4966 /* | |
4967 * Extra security check: When a swap file is a symbolic link, this | |
4968 * is most likely a symlink attack. | |
4969 */ | |
4970 if (mch_lstat((char *)fname, &sb) < 0) | |
4971 #else | |
4972 # ifdef AMIGA | |
4973 fh = Open((UBYTE *)fname, (long)MODE_NEWFILE); | |
4974 /* | |
4975 * on the Amiga mch_getperm() will return -1 when the file exists | |
4976 * but is being used by another program. This happens if you edit | |
4977 * a file twice. | |
4978 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
4979 if (fh != (BPTR)NULL) // can open file, OK |
7 | 4980 { |
4981 Close(fh); | |
4982 mch_remove(fname); | |
4983 break; | |
4984 } | |
4985 if (IoErr() != ERROR_OBJECT_IN_USE | |
4986 && IoErr() != ERROR_OBJECT_EXISTS) | |
4987 # endif | |
4988 #endif | |
4989 break; | |
4990 } | |
4991 | |
4992 /* | |
4993 * A file name equal to old_fname is OK to use. | |
4994 */ | |
4995 if (old_fname != NULL && fnamecmp(fname, old_fname) == 0) | |
4996 break; | |
4997 | |
4998 /* | |
4999 * get here when file already exists | |
5000 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5001 if (fname[n - 2] == 'w' && fname[n - 1] == 'p') // first try |
7 | 5002 { |
5003 /* | |
5004 * on MS-DOS compatible filesystems (e.g. messydos) file.doc.swp | |
5005 * and file.doc are the same file. To guess if this problem is | |
5006 * present try if file.doc.swx exists. If it does, we set | |
5007 * buf->b_shortname and try file_doc.swp (dots replaced by | |
5008 * underscores for this file), and try again. If it doesn't we | |
5009 * assume that "file.doc.swp" already exists. | |
5010 */ | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5011 if (!(buf->b_p_sn || buf->b_shortname)) // not tried yet |
7 | 5012 { |
5013 fname[n - 1] = 'x'; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5014 r = mch_getperm(fname); // try "file.swx" |
7 | 5015 fname[n - 1] = 'p'; |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5016 if (r >= 0) // "file.swx" seems to exist |
7 | 5017 { |
5018 buf->b_shortname = TRUE; | |
5019 vim_free(fname); | |
5432 | 5020 fname = makeswapname(buf_fname, buf->b_ffname, |
460 | 5021 buf, dir_name); |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5022 continue; // try again with '.' replaced with '_' |
7 | 5023 } |
5024 } | |
5025 /* | |
5026 * If we get here the ".swp" file really exists. | |
5027 * Give an error message, unless recovering, no file name, we are | |
5028 * viewing a help file or when the path of the file is different | |
5029 * (happens when all .swp files are in one directory). | |
5030 */ | |
5432 | 5031 if (!recoverymode && buf_fname != NULL |
17632
5278e5a2a4e3
patch 8.1.1813: ATTENTION prompt for a preview popup window
Bram Moolenaar <Bram@vim.org>
parents:
17454
diff
changeset
|
5032 && !buf->b_help |
5278e5a2a4e3
patch 8.1.1813: ATTENTION prompt for a preview popup window
Bram Moolenaar <Bram@vim.org>
parents:
17454
diff
changeset
|
5033 && !(buf->b_flags & (BF_DUMMY | BF_NO_SEA))) |
7 | 5034 { |
5035 int fd; | |
5036 struct block0 b0; | |
5037 int differ = FALSE; | |
5038 | |
5039 /* | |
5040 * Try to read block 0 from the swap file to get the original | |
5041 * file name (and inode number). | |
5042 */ | |
5043 fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0); | |
5044 if (fd >= 0) | |
5045 { | |
2664 | 5046 if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) |
7 | 5047 { |
5048 /* | |
39 | 5049 * If the swapfile has the same directory as the |
5050 * buffer don't compare the directory names, they can | |
5051 * have a different mountpoint. | |
7 | 5052 */ |
39 | 5053 if (b0.b0_flags & B0_SAME_DIR) |
5054 { | |
5055 if (fnamecmp(gettail(buf->b_ffname), | |
5056 gettail(b0.b0_fname)) != 0 | |
5057 || !same_directory(fname, buf->b_ffname)) | |
594 | 5058 { |
5059 #ifdef CHECK_INODE | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5060 // Symlinks may point to the same file even |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5061 // when the name differs, need to check the |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5062 // inode too. |
594 | 5063 expand_env(b0.b0_fname, NameBuff, MAXPATHL); |
5064 if (fnamecmp_ino(buf->b_ffname, NameBuff, | |
5065 char_to_long(b0.b0_ino))) | |
5066 #endif | |
5067 differ = TRUE; | |
5068 } | |
39 | 5069 } |
5070 else | |
5071 { | |
5072 /* | |
5073 * The name in the swap file may be | |
5074 * "~user/path/file". Expand it first. | |
5075 */ | |
5076 expand_env(b0.b0_fname, NameBuff, MAXPATHL); | |
7 | 5077 #ifdef CHECK_INODE |
39 | 5078 if (fnamecmp_ino(buf->b_ffname, NameBuff, |
594 | 5079 char_to_long(b0.b0_ino))) |
39 | 5080 differ = TRUE; |
7 | 5081 #else |
39 | 5082 if (fnamecmp(NameBuff, buf->b_ffname) != 0) |
5083 differ = TRUE; | |
7 | 5084 #endif |
39 | 5085 } |
7 | 5086 } |
5087 close(fd); | |
5088 } | |
5089 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5090 // give the ATTENTION message when there is an old swap file |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5091 // for the current file, and the buffer was not recovered. |
7 | 5092 if (differ == FALSE && !(curbuf->b_flags & BF_RECOVERED) |
5093 && vim_strchr(p_shm, SHM_ATTENTION) == NULL) | |
5094 { | |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5095 sea_choice_T choice = SEA_CHOICE_NONE; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5096 stat_T st; |
7 | 5097 #ifdef CREATE_DUMMY_FILE |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5098 int did_use_dummy = FALSE; |
7 | 5099 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5100 // Avoid getting a warning for the file being created |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5101 // outside of Vim, it was created at the start of this |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5102 // function. Delete the file now, because Vim might exit |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5103 // here if the window is closed. |
7 | 5104 if (dummyfd != NULL) |
5105 { | |
5106 fclose(dummyfd); | |
5107 dummyfd = NULL; | |
5432 | 5108 mch_remove(buf_fname); |
7 | 5109 did_use_dummy = TRUE; |
5110 } | |
5111 #endif | |
5112 | |
16455
1ae13586edf8
patch 8.1.1232: can't build on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
16453
diff
changeset
|
5113 #ifdef HAVE_PROCESS_STILL_RUNNING |
7 | 5114 process_still_running = FALSE; |
5115 #endif | |
16453
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
5116 // It's safe to delete the swap file if all these are true: |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
5117 // - the edited file exists |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
5118 // - the swap file has no changes and looks OK |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
5119 if (mch_stat((char *)buf->b_fname, &st) == 0 |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
5120 && swapfile_unchanged(fname)) |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
5121 { |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5122 choice = SEA_CHOICE_DELETE; |
16453
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
5123 if (p_verbose > 0) |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
5124 verb_msg(_("Found a swap file that is not useful, deleting it")); |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
5125 } |
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
5126 |
13380
69517d67421f
patch 8.0.1564: too many #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
13244
diff
changeset
|
5127 #if defined(FEAT_EVAL) |
580 | 5128 /* |
5129 * If there is an SwapExists autocommand and we can handle | |
5130 * the response, trigger it. It may return 0 to ask the | |
5131 * user anyway. | |
5132 */ | |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5133 if (choice == SEA_CHOICE_NONE |
16453
4e9bea9b8025
patch 8.1.1231: asking about existing swap file unnecessarily
Bram Moolenaar <Bram@vim.org>
parents:
16451
diff
changeset
|
5134 && swap_exists_action != SEA_NONE |
5432 | 5135 && has_autocmd(EVENT_SWAPEXISTS, buf_fname, buf)) |
580 | 5136 choice = do_swapexists(buf, fname); |
5137 #endif | |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5138 |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5139 if (choice == SEA_CHOICE_NONE |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5140 && swap_exists_action == SEA_READONLY) |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5141 { |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5142 // always open readonly. |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5143 choice = SEA_CHOICE_READONLY; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5144 } |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5145 |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5146 if (choice == SEA_CHOICE_NONE) |
7 | 5147 { |
580 | 5148 #ifdef FEAT_GUI |
14903
c1ee9f32bec3
patch 8.1.0463: "simalt ~x" in .vimrc blocks swap file prompt
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
5149 // If we are supposed to start the GUI but it wasn't |
c1ee9f32bec3
patch 8.1.0463: "simalt ~x" in .vimrc blocks swap file prompt
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
5150 // completely started yet, start it now. This makes |
c1ee9f32bec3
patch 8.1.0463: "simalt ~x" in .vimrc blocks swap file prompt
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
5151 // the messages displayed in the Vim window when |
c1ee9f32bec3
patch 8.1.0463: "simalt ~x" in .vimrc blocks swap file prompt
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
5152 // loading a session from the .gvimrc file. |
580 | 5153 if (gui.starting && !gui.in_use) |
16451
7ae2396cef62
patch 8.1.1230: a lot of code is shared between vim.exe and gvim.exe
Bram Moolenaar <Bram@vim.org>
parents:
16162
diff
changeset
|
5154 gui_start(NULL); |
580 | 5155 #endif |
14903
c1ee9f32bec3
patch 8.1.0463: "simalt ~x" in .vimrc blocks swap file prompt
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
5156 // Show info about the existing swap file. |
580 | 5157 attention_message(buf, fname); |
5158 | |
14903
c1ee9f32bec3
patch 8.1.0463: "simalt ~x" in .vimrc blocks swap file prompt
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
5159 // We don't want a 'q' typed at the more-prompt |
c1ee9f32bec3
patch 8.1.0463: "simalt ~x" in .vimrc blocks swap file prompt
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
5160 // interrupt loading a file. |
580 | 5161 got_int = FALSE; |
14903
c1ee9f32bec3
patch 8.1.0463: "simalt ~x" in .vimrc blocks swap file prompt
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
5162 |
c1ee9f32bec3
patch 8.1.0463: "simalt ~x" in .vimrc blocks swap file prompt
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
5163 // If vimrc has "simalt ~x" we don't want it to |
c1ee9f32bec3
patch 8.1.0463: "simalt ~x" in .vimrc blocks swap file prompt
Bram Moolenaar <Bram@vim.org>
parents:
14862
diff
changeset
|
5164 // interfere with the prompt here. |
14909
c97b4b537572
patch 8.1.0466: autocmd test fails
Bram Moolenaar <Bram@vim.org>
parents:
14903
diff
changeset
|
5165 flush_buffers(FLUSH_TYPEAHEAD); |
7 | 5166 } |
5167 | |
5168 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) | |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5169 if (swap_exists_action != SEA_NONE |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5170 && choice == SEA_CHOICE_NONE) |
7 | 5171 { |
5172 char_u *name; | |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5173 int dialog_result; |
7 | 5174 |
16764
ef00b6bc186b
patch 8.1.1384: using "int" for alloc() often results in compiler warnings
Bram Moolenaar <Bram@vim.org>
parents:
16738
diff
changeset
|
5175 name = alloc(STRLEN(fname) |
7 | 5176 + STRLEN(_("Swap file \"")) |
16764
ef00b6bc186b
patch 8.1.1384: using "int" for alloc() often results in compiler warnings
Bram Moolenaar <Bram@vim.org>
parents:
16738
diff
changeset
|
5177 + STRLEN(_("\" already exists!")) + 5); |
7 | 5178 if (name != NULL) |
5179 { | |
5180 STRCPY(name, _("Swap file \"")); | |
5181 home_replace(NULL, fname, name + STRLEN(name), | |
5182 1000, TRUE); | |
5183 STRCAT(name, _("\" already exists!")); | |
5184 } | |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5185 dialog_result = do_dialog(VIM_WARNING, |
7 | 5186 (char_u *)_("VIM - ATTENTION"), |
5187 name == NULL | |
5188 ? (char_u *)_("Swap file already exists!") | |
5189 : name, | |
16455
1ae13586edf8
patch 8.1.1232: can't build on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
16453
diff
changeset
|
5190 # ifdef HAVE_PROCESS_STILL_RUNNING |
7 | 5191 process_still_running |
5192 ? (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover\n&Quit\n&Abort") : | |
5193 # endif | |
2684 | 5194 (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover\n&Delete it\n&Quit\n&Abort"), 1, NULL, FALSE); |
580 | 5195 |
16455
1ae13586edf8
patch 8.1.1232: can't build on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
16453
diff
changeset
|
5196 # ifdef HAVE_PROCESS_STILL_RUNNING |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5197 if (process_still_running && dialog_result >= 4) |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5198 // compensate for missing "Delete it" button |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5199 dialog_result++; |
580 | 5200 # endif |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5201 choice = dialog_result; |
580 | 5202 vim_free(name); |
5203 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5204 // pretend screen didn't scroll, need redraw anyway |
580 | 5205 msg_scrolled = 0; |
29732
89e1d67814a9
patch 9.0.0206: redraw flags are not named specifically
Bram Moolenaar <Bram@vim.org>
parents:
29682
diff
changeset
|
5206 redraw_all_later(UPD_NOT_VALID); |
580 | 5207 } |
5208 #endif | |
5209 | |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5210 switch (choice) |
580 | 5211 { |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5212 case SEA_CHOICE_READONLY: |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5213 buf->b_p_ro = TRUE; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5214 break; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5215 case SEA_CHOICE_EDIT: |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5216 break; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5217 case SEA_CHOICE_RECOVER: |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5218 swap_exists_action = SEA_RECOVER; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5219 break; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5220 case SEA_CHOICE_DELETE: |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5221 mch_remove(fname); |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5222 break; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5223 case SEA_CHOICE_QUIT: |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5224 swap_exists_action = SEA_QUIT; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5225 break; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5226 case SEA_CHOICE_ABORT: |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5227 swap_exists_action = SEA_QUIT; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5228 got_int = TRUE; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5229 break; |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5230 case SEA_CHOICE_NONE: |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5231 msg_puts("\n"); |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5232 if (msg_silent == 0) |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5233 // call wait_return() later |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5234 need_wait_return = TRUE; |
7 | 5235 break; |
5236 } | |
28319
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5237 |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5238 // If the file was deleted this fname can be used. |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5239 if (choice != SEA_CHOICE_NONE && mch_getperm(fname) < 0) |
427600f3b1c5
patch 8.2.4685: when a swap file is found for a popup there is no dialog
Bram Moolenaar <Bram@vim.org>
parents:
28175
diff
changeset
|
5240 break; |
7 | 5241 |
5242 #ifdef CREATE_DUMMY_FILE | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5243 // Going to try another name, need the dummy file again. |
7 | 5244 if (did_use_dummy) |
5432 | 5245 dummyfd = mch_fopen((char *)buf_fname, "w"); |
7 | 5246 #endif |
5247 } | |
5248 } | |
5249 } | |
5250 | |
5251 /* | |
5252 * Change the ".swp" extension to find another file that can be used. | |
5253 * First decrement the last char: ".swo", ".swn", etc. | |
5254 * If that still isn't enough decrement the last but one char: ".svz" | |
9 | 5255 * Can happen when editing many "No Name" buffers. |
7 | 5256 */ |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5257 if (fname[n - 1] == 'a') // ".s?a" |
7 | 5258 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5259 if (fname[n - 2] == 'a') // ".saa": tried enough, give up |
7 | 5260 { |
26909
aa65d1808bd0
patch 8.2.3983: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26897
diff
changeset
|
5261 emsg(_(e_too_many_swap_files_found)); |
13244
ac42c4b11dbc
patch 8.0.1496: clearing a pointer takes two lines
Christian Brabandt <cb@256bit.org>
parents:
12975
diff
changeset
|
5262 VIM_CLEAR(fname); |
7 | 5263 break; |
5264 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5265 --fname[n - 2]; // ".svz", ".suz", etc. |
7 | 5266 fname[n - 1] = 'z' + 1; |
5267 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5268 --fname[n - 1]; // ".swo", ".swn", etc. |
7 | 5269 } |
5270 | |
5271 vim_free(dir_name); | |
5272 #ifdef CREATE_DUMMY_FILE | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5273 if (dummyfd != NULL) // file has been created temporarily |
7 | 5274 { |
5275 fclose(dummyfd); | |
5432 | 5276 mch_remove(buf_fname); |
7 | 5277 } |
5278 #endif | |
15868
7fad90423bd2
patch 8.1.0941: macros for MS-Windows are inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
15636
diff
changeset
|
5279 #ifdef MSWIN |
5432 | 5280 if (buf_fname != buf->b_fname) |
5281 vim_free(buf_fname); | |
5282 #endif | |
7 | 5283 return fname; |
5284 } | |
5285 | |
5286 static int | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5287 b0_magic_wrong(ZERO_BL *b0p) |
7 | 5288 { |
5289 return (b0p->b0_magic_long != (long)B0_MAGIC_LONG | |
5290 || b0p->b0_magic_int != (int)B0_MAGIC_INT | |
5291 || b0p->b0_magic_short != (short)B0_MAGIC_SHORT | |
5292 || b0p->b0_magic_char != B0_MAGIC_CHAR); | |
5293 } | |
5294 | |
5295 #ifdef CHECK_INODE | |
5296 /* | |
5297 * Compare current file name with file name from swap file. | |
5298 * Try to use inode numbers when possible. | |
5299 * Return non-zero when files are different. | |
5300 * | |
5301 * When comparing file names a few things have to be taken into consideration: | |
5302 * - When working over a network the full path of a file depends on the host. | |
5303 * We check the inode number if possible. It is not 100% reliable though, | |
5304 * because the device number cannot be used over a network. | |
5305 * - When a file does not exist yet (editing a new file) there is no inode | |
5306 * number. | |
5307 * - The file name in a swap file may not be valid on the current host. The | |
5308 * "~user" form is used whenever possible to avoid this. | |
5309 * | |
5310 * This is getting complicated, let's make a table: | |
5311 * | |
5312 * ino_c ino_s fname_c fname_s differ = | |
5313 * | |
5314 * both files exist -> compare inode numbers: | |
5315 * != 0 != 0 X X ino_c != ino_s | |
5316 * | |
5317 * inode number(s) unknown, file names available -> compare file names | |
5318 * == 0 X OK OK fname_c != fname_s | |
5319 * X == 0 OK OK fname_c != fname_s | |
5320 * | |
5321 * current file doesn't exist, file for swap file exist, file name(s) not | |
5322 * available -> probably different | |
5323 * == 0 != 0 FAIL X TRUE | |
5324 * == 0 != 0 X FAIL TRUE | |
5325 * | |
5326 * current file exists, inode for swap unknown, file name(s) not | |
5327 * available -> probably different | |
5328 * != 0 == 0 FAIL X TRUE | |
5329 * != 0 == 0 X FAIL TRUE | |
5330 * | |
5331 * current file doesn't exist, inode for swap unknown, one file name not | |
5332 * available -> probably different | |
5333 * == 0 == 0 FAIL OK TRUE | |
5334 * == 0 == 0 OK FAIL TRUE | |
5335 * | |
5336 * current file doesn't exist, inode for swap unknown, both file names not | |
13896
4d5a1ada407e
patch 8.0.1819: swap file warning for file with non-existing directory
Christian Brabandt <cb@256bit.org>
parents:
13632
diff
changeset
|
5337 * available -> compare file names |
4d5a1ada407e
patch 8.0.1819: swap file warning for file with non-existing directory
Christian Brabandt <cb@256bit.org>
parents:
13632
diff
changeset
|
5338 * == 0 == 0 FAIL FAIL fname_c != fname_s |
7 | 5339 * |
5340 * Note that when the ino_t is 64 bits, only the last 32 will be used. This | |
5341 * can't be changed without making the block 0 incompatible with 32 bit | |
5342 * versions. | |
5343 */ | |
5344 | |
5345 static int | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5346 fnamecmp_ino( |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5347 char_u *fname_c, // current file name |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5348 char_u *fname_s, // file name from swap file |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5349 long ino_block0) |
7 | 5350 { |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
5351 stat_T st; |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5352 ino_t ino_c = 0; // ino of current file |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5353 ino_t ino_s; // ino of file from swap file |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5354 char_u buf_c[MAXPATHL]; // full path of fname_c |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5355 char_u buf_s[MAXPATHL]; // full path of fname_s |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5356 int retval_c; // flag: buf_c valid |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5357 int retval_s; // flag: buf_s valid |
7 | 5358 |
5359 if (mch_stat((char *)fname_c, &st) == 0) | |
5360 ino_c = (ino_t)st.st_ino; | |
5361 | |
5362 /* | |
5363 * First we try to get the inode from the file name, because the inode in | |
5364 * the swap file may be outdated. If that fails (e.g. this path is not | |
5365 * valid on this machine), use the inode from block 0. | |
5366 */ | |
5367 if (mch_stat((char *)fname_s, &st) == 0) | |
5368 ino_s = (ino_t)st.st_ino; | |
5369 else | |
5370 ino_s = (ino_t)ino_block0; | |
5371 | |
5372 if (ino_c && ino_s) | |
5373 return (ino_c != ino_s); | |
5374 | |
5375 /* | |
5376 * One of the inode numbers is unknown, try a forced vim_FullName() and | |
5377 * compare the file names. | |
5378 */ | |
5379 retval_c = vim_FullName(fname_c, buf_c, MAXPATHL, TRUE); | |
5380 retval_s = vim_FullName(fname_s, buf_s, MAXPATHL, TRUE); | |
5381 if (retval_c == OK && retval_s == OK) | |
13896
4d5a1ada407e
patch 8.0.1819: swap file warning for file with non-existing directory
Christian Brabandt <cb@256bit.org>
parents:
13632
diff
changeset
|
5382 return STRCMP(buf_c, buf_s) != 0; |
7 | 5383 |
5384 /* | |
5385 * Can't compare inodes or file names, guess that the files are different, | |
13896
4d5a1ada407e
patch 8.0.1819: swap file warning for file with non-existing directory
Christian Brabandt <cb@256bit.org>
parents:
13632
diff
changeset
|
5386 * unless both appear not to exist at all, then compare with the file name |
4d5a1ada407e
patch 8.0.1819: swap file warning for file with non-existing directory
Christian Brabandt <cb@256bit.org>
parents:
13632
diff
changeset
|
5387 * in the swap file. |
7 | 5388 */ |
5389 if (ino_s == 0 && ino_c == 0 && retval_c == FAIL && retval_s == FAIL) | |
13896
4d5a1ada407e
patch 8.0.1819: swap file warning for file with non-existing directory
Christian Brabandt <cb@256bit.org>
parents:
13632
diff
changeset
|
5390 return STRCMP(fname_c, fname_s) != 0; |
7 | 5391 return TRUE; |
5392 } | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5393 #endif // CHECK_INODE |
7 | 5394 |
5395 /* | |
5396 * Move a long integer into a four byte character array. | |
5397 * Used for machine independency in block zero. | |
5398 */ | |
5399 static void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5400 long_to_char(long n, char_u *s) |
7 | 5401 { |
5402 s[0] = (char_u)(n & 0xff); | |
5403 n = (unsigned)n >> 8; | |
5404 s[1] = (char_u)(n & 0xff); | |
5405 n = (unsigned)n >> 8; | |
5406 s[2] = (char_u)(n & 0xff); | |
5407 n = (unsigned)n >> 8; | |
5408 s[3] = (char_u)(n & 0xff); | |
5409 } | |
5410 | |
5411 static long | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5412 char_to_long(char_u *s) |
7 | 5413 { |
5414 long retval; | |
5415 | |
5416 retval = s[3]; | |
5417 retval <<= 8; | |
5418 retval |= s[2]; | |
5419 retval <<= 8; | |
5420 retval |= s[1]; | |
5421 retval <<= 8; | |
5422 retval |= s[0]; | |
5423 | |
5424 return retval; | |
5425 } | |
5426 | |
39 | 5427 /* |
5428 * Set the flags in the first block of the swap file: | |
5429 * - file is modified or not: buf->b_changed | |
5430 * - 'fileformat' | |
5431 * - 'fileencoding' | |
5432 */ | |
7 | 5433 void |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5434 ml_setflags(buf_T *buf) |
7 | 5435 { |
5436 bhdr_T *hp; | |
5437 ZERO_BL *b0p; | |
5438 | |
5439 if (!buf->b_ml.ml_mfp) | |
5440 return; | |
5441 for (hp = buf->b_ml.ml_mfp->mf_used_last; hp != NULL; hp = hp->bh_prev) | |
5442 { | |
5443 if (hp->bh_bnum == 0) | |
5444 { | |
5445 b0p = (ZERO_BL *)(hp->bh_data); | |
39 | 5446 b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0; |
5447 b0p->b0_flags = (b0p->b0_flags & ~B0_FF_MASK) | |
5448 | (get_fileformat(buf) + 1); | |
5449 add_b0_fenc(b0p, buf); | |
7 | 5450 hp->bh_flags |= BH_DIRTY; |
5451 mf_sync(buf->b_ml.ml_mfp, MFS_ZERO); | |
5452 break; | |
5453 } | |
5454 } | |
5455 } | |
5456 | |
2267 | 5457 #if defined(FEAT_CRYPT) || defined(PROTO) |
5458 /* | |
5459 * If "data" points to a data block encrypt the text in it and return a copy | |
5460 * in allocated memory. Return NULL when out of memory. | |
5461 * Otherwise return "data". | |
5462 */ | |
5463 char_u * | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5464 ml_encrypt_data( |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5465 memfile_T *mfp, |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5466 char_u *data, |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
5467 off_T offset, |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5468 unsigned size) |
2267 | 5469 { |
5470 DATA_BL *dp = (DATA_BL *)data; | |
5471 char_u *head_end; | |
5472 char_u *text_start; | |
5473 char_u *new_data; | |
5474 int text_len; | |
6122 | 5475 cryptstate_T *state; |
2267 | 5476 |
5477 if (dp->db_id != DATA_ID) | |
5478 return data; | |
5479 | |
6817 | 5480 state = ml_crypt_prepare(mfp, offset, FALSE); |
5481 if (state == NULL) | |
5482 return data; | |
5483 | |
16825
ce04ebdf26b8
patch 8.1.1414: alloc() returning "char_u *" causes a lot of type casts
Bram Moolenaar <Bram@vim.org>
parents:
16786
diff
changeset
|
5484 new_data = alloc(size); |
2267 | 5485 if (new_data == NULL) |
5486 return NULL; | |
5487 head_end = (char_u *)(&dp->db_index[dp->db_line_count]); | |
5488 text_start = (char_u *)dp + dp->db_txt_start; | |
5489 text_len = size - dp->db_txt_start; | |
5490 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5491 // Copy the header and the text. |
2267 | 5492 mch_memmove(new_data, dp, head_end - (char_u *)dp); |
5493 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5494 // Encrypt the text. |
24970
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
5495 crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start, |
7e9e53a0368f
patch 8.2.3022: available encryption methods are not strong enough
Bram Moolenaar <Bram@vim.org>
parents:
24856
diff
changeset
|
5496 FALSE); |
6122 | 5497 crypt_free_state(state); |
2267 | 5498 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5499 // Clear the gap. |
2267 | 5500 if (head_end < text_start) |
5501 vim_memset(new_data + (head_end - data), 0, text_start - head_end); | |
5502 | |
5503 return new_data; | |
5504 } | |
5505 | |
5506 /* | |
6817 | 5507 * Decrypt the text in "data" if it points to an encrypted data block. |
2267 | 5508 */ |
5509 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5510 ml_decrypt_data( |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5511 memfile_T *mfp, |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5512 char_u *data, |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
5513 off_T offset, |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5514 unsigned size) |
2267 | 5515 { |
5516 DATA_BL *dp = (DATA_BL *)data; | |
5517 char_u *head_end; | |
5518 char_u *text_start; | |
5519 int text_len; | |
6122 | 5520 cryptstate_T *state; |
2267 | 5521 |
31728
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5522 if (dp->db_id != DATA_ID) |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5523 return; |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5524 |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5525 head_end = (char_u *)(&dp->db_index[dp->db_line_count]); |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5526 text_start = (char_u *)dp + dp->db_txt_start; |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5527 text_len = dp->db_txt_end - dp->db_txt_start; |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5528 |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5529 if (head_end > text_start || dp->db_txt_start > size |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5530 || dp->db_txt_end > size) |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5531 return; // data was messed up |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5532 |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5533 state = ml_crypt_prepare(mfp, offset, TRUE); |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5534 if (state == NULL) |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5535 return; |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5536 |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5537 // Decrypt the text in place. |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5538 crypt_decode_inplace(state, text_start, text_len, FALSE); |
238ca27dbfd2
patch 9.0.1196: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31513
diff
changeset
|
5539 crypt_free_state(state); |
2267 | 5540 } |
5541 | |
5542 /* | |
5543 * Prepare for encryption/decryption, using the key, seed and offset. | |
6122 | 5544 * Return an allocated cryptstate_T *. |
32299
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5545 * Note: Encryption not supported for SODIUM |
2267 | 5546 */ |
6122 | 5547 static cryptstate_T * |
9387
f094d4085014
commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe
Christian Brabandt <cb@256bit.org>
parents:
9295
diff
changeset
|
5548 ml_crypt_prepare(memfile_T *mfp, off_T offset, int reading) |
2267 | 5549 { |
5550 buf_T *buf = mfp->mf_buffer; | |
5551 char_u salt[50]; | |
6122 | 5552 int method_nr; |
2267 | 5553 char_u *key; |
32299
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5554 crypt_arg_T arg; |
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5555 |
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5556 CLEAR_FIELD(arg); |
2267 | 5557 if (reading && mfp->mf_old_key != NULL) |
5558 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5559 // Reading back blocks with the previous key/method/seed. |
6122 | 5560 method_nr = mfp->mf_old_cm; |
2267 | 5561 key = mfp->mf_old_key; |
32299
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5562 arg.cat_seed = mfp->mf_old_seed; |
2267 | 5563 } |
5564 else | |
5565 { | |
6122 | 5566 method_nr = crypt_get_method_nr(buf); |
2267 | 5567 key = buf->b_p_key; |
32299
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5568 arg.cat_seed = mfp->mf_seed; |
2267 | 5569 } |
32299
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5570 |
6817 | 5571 if (*key == NUL) |
5572 return NULL; | |
2267 | 5573 |
6122 | 5574 if (method_nr == CRYPT_M_ZIP) |
2267 | 5575 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5576 // For PKzip: Append the offset to the key, so that we use a different |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5577 // key for every block. |
2267 | 5578 vim_snprintf((char *)salt, sizeof(salt), "%s%ld", key, (long)offset); |
32299
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5579 arg.cat_seed = NULL; |
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5580 arg.cat_init_from_file = FALSE; |
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5581 |
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5582 return crypt_create(method_nr, salt, &arg); |
2267 | 5583 } |
6122 | 5584 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5585 // Using blowfish or better: add salt and seed. We use the byte offset |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5586 // of the block for the salt. |
6122 | 5587 vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset); |
32299
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5588 |
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5589 arg.cat_salt = salt; |
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5590 arg.cat_salt_len = (int)STRLEN(salt); |
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5591 arg.cat_seed_len = MF_SEED_LEN; |
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5592 arg.cat_add_len = 0; |
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5593 arg.cat_add = NULL; |
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5594 arg.cat_init_from_file = FALSE; |
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5595 |
3d4e28569a6d
patch 9.0.1481: decrypting with libsodium may fail if the library changes
Bram Moolenaar <Bram@vim.org>
parents:
32290
diff
changeset
|
5596 return crypt_create(method_nr, key, &arg); |
2267 | 5597 } |
5598 | |
5599 #endif | |
5600 | |
5601 | |
7 | 5602 #if defined(FEAT_BYTEOFF) || defined(PROTO) |
5603 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5604 #define MLCS_MAXL 800 // max no of lines in chunk |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5605 #define MLCS_MINL 400 // should be half of MLCS_MAXL |
7 | 5606 |
5607 /* | |
2407
6bc102a4bff8
Fix memory access to 'cryptmethod' during recovery. (Dominique Pelle)
Bram Moolenaar <bram@vim.org>
parents:
2394
diff
changeset
|
5608 * Keep information for finding byte offset of a line, updtype may be one of: |
7 | 5609 * ML_CHNK_ADDLINE: Add len to parent chunk, possibly splitting it |
5610 * Careful: ML_CHNK_ADDLINE may cause ml_find_line() to be called. | |
5611 * ML_CHNK_DELLINE: Subtract len from parent chunk, possibly deleting it | |
5612 * ML_CHNK_UPDLINE: Add len to parent chunk, as a signed entity. | |
5613 */ | |
5614 static void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5615 ml_updatechunk( |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5616 buf_T *buf, |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5617 linenr_T line, |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5618 long len, |
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5619 int updtype) |
7 | 5620 { |
5621 static buf_T *ml_upd_lastbuf = NULL; | |
5622 static linenr_T ml_upd_lastline; | |
5623 static linenr_T ml_upd_lastcurline; | |
5624 static int ml_upd_lastcurix; | |
5625 | |
5626 linenr_T curline = ml_upd_lastcurline; | |
5627 int curix = ml_upd_lastcurix; | |
5628 long size; | |
5629 chunksize_T *curchnk; | |
5630 int rest; | |
5631 bhdr_T *hp; | |
5632 DATA_BL *dp; | |
5633 | |
5634 if (buf->b_ml.ml_usedchunks == -1 || len == 0) | |
5635 return; | |
5636 if (buf->b_ml.ml_chunksize == NULL) | |
5637 { | |
16825
ce04ebdf26b8
patch 8.1.1414: alloc() returning "char_u *" causes a lot of type casts
Bram Moolenaar <Bram@vim.org>
parents:
16786
diff
changeset
|
5638 buf->b_ml.ml_chunksize = ALLOC_MULT(chunksize_T, 100); |
7 | 5639 if (buf->b_ml.ml_chunksize == NULL) |
5640 { | |
5641 buf->b_ml.ml_usedchunks = -1; | |
5642 return; | |
5643 } | |
5644 buf->b_ml.ml_numchunks = 100; | |
5645 buf->b_ml.ml_usedchunks = 1; | |
5646 buf->b_ml.ml_chunksize[0].mlcs_numlines = 1; | |
5647 buf->b_ml.ml_chunksize[0].mlcs_totalsize = 1; | |
5648 } | |
5649 | |
5650 if (updtype == ML_CHNK_UPDLINE && buf->b_ml.ml_line_count == 1) | |
5651 { | |
5652 /* | |
5653 * First line in empty buffer from ml_flush_line() -- reset | |
5654 */ | |
5655 buf->b_ml.ml_usedchunks = 1; | |
5656 buf->b_ml.ml_chunksize[0].mlcs_numlines = 1; | |
15138
9df130fd5e0d
patch 8.1.0579: cannot attach properties to text
Bram Moolenaar <Bram@vim.org>
parents:
14980
diff
changeset
|
5657 buf->b_ml.ml_chunksize[0].mlcs_totalsize = (long)buf->b_ml.ml_line_len; |
7 | 5658 return; |
5659 } | |
5660 | |
5661 /* | |
5662 * Find chunk that our line belongs to, curline will be at start of the | |
5663 * chunk. | |
5664 */ | |
5665 if (buf != ml_upd_lastbuf || line != ml_upd_lastline + 1 | |
5666 || updtype != ML_CHNK_ADDLINE) | |
5667 { | |
5668 for (curline = 1, curix = 0; | |
5669 curix < buf->b_ml.ml_usedchunks - 1 | |
5670 && line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines; | |
5671 curix++) | |
5672 curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines; | |
5673 } | |
14980
c98810dfebaf
patch 8.1.0501: cppcheck warns for using array index before bounds check
Bram Moolenaar <Bram@vim.org>
parents:
14923
diff
changeset
|
5674 else if (curix < buf->b_ml.ml_usedchunks - 1 |
c98810dfebaf
patch 8.1.0501: cppcheck warns for using array index before bounds check
Bram Moolenaar <Bram@vim.org>
parents:
14923
diff
changeset
|
5675 && line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines) |
7 | 5676 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5677 // Adjust cached curix & curline |
7 | 5678 curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines; |
5679 curix++; | |
5680 } | |
5681 curchnk = buf->b_ml.ml_chunksize + curix; | |
5682 | |
5683 if (updtype == ML_CHNK_DELLINE) | |
1030 | 5684 len = -len; |
7 | 5685 curchnk->mlcs_totalsize += len; |
5686 if (updtype == ML_CHNK_ADDLINE) | |
5687 { | |
5688 curchnk->mlcs_numlines++; | |
5689 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5690 // May resize here so we don't have to do it in both cases below |
7 | 5691 if (buf->b_ml.ml_usedchunks + 1 >= buf->b_ml.ml_numchunks) |
5692 { | |
6596 | 5693 chunksize_T *t_chunksize = buf->b_ml.ml_chunksize; |
5694 | |
7 | 5695 buf->b_ml.ml_numchunks = buf->b_ml.ml_numchunks * 3 / 2; |
21915
2559dc02bd64
patch 8.2.1507: using malloc() directly
Bram Moolenaar <Bram@vim.org>
parents:
21337
diff
changeset
|
5696 buf->b_ml.ml_chunksize = vim_realloc(buf->b_ml.ml_chunksize, |
7 | 5697 sizeof(chunksize_T) * buf->b_ml.ml_numchunks); |
5698 if (buf->b_ml.ml_chunksize == NULL) | |
5699 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5700 // Hmmmm, Give up on offset for this buffer |
6596 | 5701 vim_free(t_chunksize); |
7 | 5702 buf->b_ml.ml_usedchunks = -1; |
5703 return; | |
5704 } | |
5705 } | |
5706 | |
5707 if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL) | |
5708 { | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5709 int count; // number of entries in block |
7 | 5710 int idx; |
15255
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5711 int end_idx; |
7 | 5712 int text_end; |
5713 int linecnt; | |
5714 | |
5715 mch_memmove(buf->b_ml.ml_chunksize + curix + 1, | |
5716 buf->b_ml.ml_chunksize + curix, | |
5717 (buf->b_ml.ml_usedchunks - curix) * | |
5718 sizeof(chunksize_T)); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5719 // Compute length of first half of lines in the split chunk |
7 | 5720 size = 0; |
5721 linecnt = 0; | |
5722 while (curline < buf->b_ml.ml_line_count | |
5723 && linecnt < MLCS_MINL) | |
5724 { | |
5725 if ((hp = ml_find_line(buf, curline, ML_FIND)) == NULL) | |
5726 { | |
5727 buf->b_ml.ml_usedchunks = -1; | |
5728 return; | |
5729 } | |
5730 dp = (DATA_BL *)(hp->bh_data); | |
5731 count = (long)(buf->b_ml.ml_locked_high) - | |
5732 (long)(buf->b_ml.ml_locked_low) + 1; | |
5733 idx = curline - buf->b_ml.ml_locked_low; | |
5734 curline = buf->b_ml.ml_locked_high + 1; | |
15255
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5735 |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5736 // compute index of last line to use in this MEMLINE |
7 | 5737 rest = count - idx; |
5738 if (linecnt + rest > MLCS_MINL) | |
5739 { | |
15255
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5740 end_idx = idx + MLCS_MINL - linecnt - 1; |
7 | 5741 linecnt = MLCS_MINL; |
5742 } | |
5743 else | |
5744 { | |
15255
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5745 end_idx = count - 1; |
7 | 5746 linecnt += rest; |
5747 } | |
18763
49b78d6465e5
patch 8.1.2371: FEAT_TEXT_PROP is a confusing name
Bram Moolenaar <Bram@vim.org>
parents:
18498
diff
changeset
|
5748 #ifdef FEAT_PROP_POPUP |
15255
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5749 if (buf->b_has_textprop) |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5750 { |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5751 int i; |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5752 |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5753 // We cannot use the text pointers to get the text length, |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5754 // the text prop info would also be counted. Go over the |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5755 // lines. |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5756 for (i = end_idx; i < idx; ++i) |
29682
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
5757 size += (int)STRLEN((char_u *)dp |
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
5758 + (dp->db_index[i] & DB_INDEX_MASK)) + 1; |
15255
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5759 } |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5760 else |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5761 #endif |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5762 { |
25624
0ef8ef1af478
patch 8.2.3348: line2byte() returns wrong value after adding textprop
Bram Moolenaar <Bram@vim.org>
parents:
25417
diff
changeset
|
5763 if (idx == 0) // first line in block, text at the end |
15255
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5764 text_end = dp->db_txt_end; |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5765 else |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5766 text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK); |
29682
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
5767 size += text_end |
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
5768 - ((dp->db_index[end_idx]) & DB_INDEX_MASK); |
15255
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5769 } |
7 | 5770 } |
5771 buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt; | |
5772 buf->b_ml.ml_chunksize[curix + 1].mlcs_numlines -= linecnt; | |
5773 buf->b_ml.ml_chunksize[curix].mlcs_totalsize = size; | |
5774 buf->b_ml.ml_chunksize[curix + 1].mlcs_totalsize -= size; | |
5775 buf->b_ml.ml_usedchunks++; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5776 ml_upd_lastbuf = NULL; // Force recalc of curix & curline |
7 | 5777 return; |
5778 } | |
5779 else if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MINL | |
5780 && curix == buf->b_ml.ml_usedchunks - 1 | |
5781 && buf->b_ml.ml_line_count - line <= 1) | |
5782 { | |
5783 /* | |
23229
b545334ae654
patch 8.2.2160: various typos
Bram Moolenaar <Bram@vim.org>
parents:
22959
diff
changeset
|
5784 * We are in the last chunk and it is cheap to create a new one |
7 | 5785 * after this. Do it now to avoid the loop above later on |
5786 */ | |
5787 curchnk = buf->b_ml.ml_chunksize + curix + 1; | |
5788 buf->b_ml.ml_usedchunks++; | |
5789 if (line == buf->b_ml.ml_line_count) | |
5790 { | |
5791 curchnk->mlcs_numlines = 0; | |
5792 curchnk->mlcs_totalsize = 0; | |
5793 } | |
5794 else | |
5795 { | |
5796 /* | |
5797 * Line is just prior to last, move count for last | |
5798 * This is the common case when loading a new file | |
5799 */ | |
5800 hp = ml_find_line(buf, buf->b_ml.ml_line_count, ML_FIND); | |
5801 if (hp == NULL) | |
5802 { | |
5803 buf->b_ml.ml_usedchunks = -1; | |
5804 return; | |
5805 } | |
5806 dp = (DATA_BL *)(hp->bh_data); | |
5807 if (dp->db_line_count == 1) | |
5808 rest = dp->db_txt_end - dp->db_txt_start; | |
5809 else | |
5810 rest = | |
5811 ((dp->db_index[dp->db_line_count - 2]) & DB_INDEX_MASK) | |
5812 - dp->db_txt_start; | |
5813 curchnk->mlcs_totalsize = rest; | |
5814 curchnk->mlcs_numlines = 1; | |
5815 curchnk[-1].mlcs_totalsize -= rest; | |
5816 curchnk[-1].mlcs_numlines -= 1; | |
5817 } | |
5818 } | |
5819 } | |
5820 else if (updtype == ML_CHNK_DELLINE) | |
5821 { | |
5822 curchnk->mlcs_numlines--; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5823 ml_upd_lastbuf = NULL; // Force recalc of curix & curline |
29682
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
5824 if (curix < buf->b_ml.ml_usedchunks - 1 |
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
5825 && curchnk->mlcs_numlines + curchnk[1].mlcs_numlines |
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
5826 <= MLCS_MINL) |
7 | 5827 { |
5828 curix++; | |
5829 curchnk = buf->b_ml.ml_chunksize + curix; | |
5830 } | |
5831 else if (curix == 0 && curchnk->mlcs_numlines <= 0) | |
5832 { | |
5833 buf->b_ml.ml_usedchunks--; | |
5834 mch_memmove(buf->b_ml.ml_chunksize, buf->b_ml.ml_chunksize + 1, | |
5835 buf->b_ml.ml_usedchunks * sizeof(chunksize_T)); | |
5836 return; | |
5837 } | |
5838 else if (curix == 0 || (curchnk->mlcs_numlines > 10 | |
29682
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
5839 && curchnk->mlcs_numlines + curchnk[-1].mlcs_numlines |
57cfb39b7842
patch 9.0.0181: textprop test with line2byte() fails on MS-Windows
Bram Moolenaar <Bram@vim.org>
parents:
29651
diff
changeset
|
5840 > MLCS_MINL)) |
7 | 5841 { |
5842 return; | |
5843 } | |
5844 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5845 // Collapse chunks |
7 | 5846 curchnk[-1].mlcs_numlines += curchnk->mlcs_numlines; |
5847 curchnk[-1].mlcs_totalsize += curchnk->mlcs_totalsize; | |
5848 buf->b_ml.ml_usedchunks--; | |
5849 if (curix < buf->b_ml.ml_usedchunks) | |
5850 mch_memmove(buf->b_ml.ml_chunksize + curix, | |
5851 buf->b_ml.ml_chunksize + curix + 1, | |
5852 (buf->b_ml.ml_usedchunks - curix) * | |
5853 sizeof(chunksize_T)); | |
5854 return; | |
5855 } | |
5856 ml_upd_lastbuf = buf; | |
5857 ml_upd_lastline = line; | |
5858 ml_upd_lastcurline = curline; | |
5859 ml_upd_lastcurix = curix; | |
5860 } | |
5861 | |
5862 /* | |
5863 * Find offset for line or line with offset. | |
169 | 5864 * Find line with offset if "lnum" is 0; return remaining offset in offp |
5865 * Find offset of line if "lnum" > 0 | |
7 | 5866 * return -1 if information is not available |
5867 */ | |
5868 long | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
5869 ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp) |
7 | 5870 { |
5871 linenr_T curline; | |
5872 int curix; | |
5873 long size; | |
5874 bhdr_T *hp; | |
5875 DATA_BL *dp; | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5876 int count; // number of entries in block |
7 | 5877 int idx; |
5878 int start_idx; | |
5879 int text_end; | |
5880 long offset; | |
5881 int len; | |
5882 int ffdos = (get_fileformat(buf) == EOL_DOS); | |
5883 int extra = 0; | |
5884 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5885 // take care of cached line first |
169 | 5886 ml_flush_line(curbuf); |
5887 | |
7 | 5888 if (buf->b_ml.ml_usedchunks == -1 |
5889 || buf->b_ml.ml_chunksize == NULL | |
169 | 5890 || lnum < 0) |
7 | 5891 return -1; |
5892 | |
5893 if (offp == NULL) | |
5894 offset = 0; | |
5895 else | |
5896 offset = *offp; | |
169 | 5897 if (lnum == 0 && offset <= 0) |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5898 return 1; // Not a "find offset" and offset 0 _must_ be in line 1 |
7 | 5899 /* |
5900 * Find the last chunk before the one containing our line. Last chunk is | |
25624
0ef8ef1af478
patch 8.2.3348: line2byte() returns wrong value after adding textprop
Bram Moolenaar <Bram@vim.org>
parents:
25417
diff
changeset
|
5901 * special because it will never qualify. |
7 | 5902 */ |
5903 curline = 1; | |
5904 curix = size = 0; | |
5905 while (curix < buf->b_ml.ml_usedchunks - 1 | |
169 | 5906 && ((lnum != 0 |
5907 && lnum >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines) | |
7 | 5908 || (offset != 0 |
5909 && offset > size + buf->b_ml.ml_chunksize[curix].mlcs_totalsize | |
27453
c7f614c9ceb3
patch 8.2.4255: theoretical computation overflow
Bram Moolenaar <Bram@vim.org>
parents:
27426
diff
changeset
|
5910 + (long)ffdos * buf->b_ml.ml_chunksize[curix].mlcs_numlines))) |
7 | 5911 { |
5912 curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines; | |
5913 size += buf->b_ml.ml_chunksize[curix].mlcs_totalsize; | |
5914 if (offset && ffdos) | |
5915 size += buf->b_ml.ml_chunksize[curix].mlcs_numlines; | |
5916 curix++; | |
5917 } | |
5918 | |
169 | 5919 while ((lnum != 0 && curline < lnum) || (offset != 0 && size < offset)) |
7 | 5920 { |
23776
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
5921 #ifdef FEAT_PROP_POPUP |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
5922 size_t textprop_total = 0; |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
5923 #endif |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
5924 |
7 | 5925 if (curline > buf->b_ml.ml_line_count |
5926 || (hp = ml_find_line(buf, curline, ML_FIND)) == NULL) | |
5927 return -1; | |
5928 dp = (DATA_BL *)(hp->bh_data); | |
5929 count = (long)(buf->b_ml.ml_locked_high) - | |
5930 (long)(buf->b_ml.ml_locked_low) + 1; | |
5931 start_idx = idx = curline - buf->b_ml.ml_locked_low; | |
19110
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5932 if (idx == 0) // first line in block, text at the end |
7 | 5933 text_end = dp->db_txt_end; |
5934 else | |
5935 text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
5936 // Compute index of last line to use in this MEMLINE |
169 | 5937 if (lnum != 0) |
7 | 5938 { |
169 | 5939 if (curline + (count - idx) >= lnum) |
5940 idx += lnum - curline - 1; | |
7 | 5941 else |
5942 idx = count - 1; | |
5943 } | |
5944 else | |
5945 { | |
5946 extra = 0; | |
19110
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5947 for (;;) |
7 | 5948 { |
19110
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5949 #ifdef FEAT_PROP_POPUP |
23776
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
5950 size_t textprop_size = 0; |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
5951 |
19110
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5952 if (buf->b_has_textprop) |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5953 { |
23776
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
5954 char_u *l1, *l2; |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
5955 |
19110
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5956 // compensate for the extra bytes taken by textprops |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5957 l1 = (char_u *)dp + ((dp->db_index[idx]) & DB_INDEX_MASK); |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5958 l2 = (char_u *)dp + (idx == 0 ? dp->db_txt_end |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5959 : ((dp->db_index[idx - 1]) & DB_INDEX_MASK)); |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5960 textprop_size = (l2 - l1) - (STRLEN(l1) + 1); |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5961 } |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5962 #endif |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5963 if (!(offset >= size |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5964 + text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK) |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5965 #ifdef FEAT_PROP_POPUP |
19133
dc6a0b05b082
patch 8.2.0126: textprop test fails
Bram Moolenaar <Bram@vim.org>
parents:
19129
diff
changeset
|
5966 - (long)(textprop_total + textprop_size) |
19110
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5967 #endif |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5968 + ffdos)) |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5969 break; |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5970 |
7 | 5971 if (ffdos) |
5972 size++; | |
19110
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5973 #ifdef FEAT_PROP_POPUP |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5974 textprop_total += textprop_size; |
e40814841406
patch 8.2.0115: byte2line() does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
18800
diff
changeset
|
5975 #endif |
7 | 5976 if (idx == count - 1) |
5977 { | |
5978 extra = 1; | |
5979 break; | |
5980 } | |
5981 idx++; | |
5982 } | |
5983 } | |
18763
49b78d6465e5
patch 8.1.2371: FEAT_TEXT_PROP is a confusing name
Bram Moolenaar <Bram@vim.org>
parents:
18498
diff
changeset
|
5984 #ifdef FEAT_PROP_POPUP |
23776
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
5985 if (buf->b_has_textprop && lnum != 0) |
15255
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5986 { |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5987 int i; |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5988 |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5989 // cannot use the db_index pointer, need to get the actual text |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5990 // lengths. |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5991 len = 0; |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5992 for (i = start_idx; i <= idx; ++i) |
23776
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
5993 { |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
5994 char_u *p = (char_u *)dp + ((dp->db_index[i]) & DB_INDEX_MASK); |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
5995 len += (int)STRLEN(p) + 1; |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
5996 } |
15255
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5997 } |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5998 else |
19e79a1ed6b6
patch 8.1.0636: line2byte() gives wrong values with text properties
Bram Moolenaar <Bram@vim.org>
parents:
15182
diff
changeset
|
5999 #endif |
23776
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
6000 len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK) |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
6001 #ifdef FEAT_PROP_POPUP |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
6002 - (long)textprop_total |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
6003 #endif |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
6004 ; |
7 | 6005 size += len; |
6006 if (offset != 0 && size >= offset) | |
6007 { | |
6008 if (size + ffdos == offset) | |
6009 *offp = 0; | |
6010 else if (idx == start_idx) | |
6011 *offp = offset - size + len; | |
6012 else | |
6013 *offp = offset - size + len | |
23776
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
6014 - (text_end - ((dp->db_index[idx - 1]) & DB_INDEX_MASK)) |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
6015 #ifdef FEAT_PROP_POPUP |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
6016 + (long)textprop_total |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
6017 #endif |
9f692a75d481
patch 8.2.2429: :goto does not work correctly with text properties
Bram Moolenaar <Bram@vim.org>
parents:
23229
diff
changeset
|
6018 ; |
7 | 6019 curline += idx - start_idx + extra; |
6020 if (curline > buf->b_ml.ml_line_count) | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
6021 return -1; // exactly one byte beyond the end |
7 | 6022 return curline; |
6023 } | |
6024 curline = buf->b_ml.ml_locked_high + 1; | |
6025 } | |
6026 | |
169 | 6027 if (lnum != 0) |
20 | 6028 { |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
6029 // Count extra CR characters. |
20 | 6030 if (ffdos) |
169 | 6031 size += lnum - 1; |
20 | 6032 |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
6033 // Don't count the last line break if 'noeol' and ('bin' or |
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
6034 // 'nofixeol'). |
6933 | 6035 if ((!buf->b_p_fixeol || buf->b_p_bin) && !buf->b_p_eol |
14579
23d6d9e9ae3e
patch 8.1.0303: line2byte() is wrong for last line with 'noeol'
Christian Brabandt <cb@256bit.org>
parents:
14475
diff
changeset
|
6036 && lnum > buf->b_ml.ml_line_count) |
20 | 6037 size -= ffdos + 1; |
6038 } | |
6039 | |
7 | 6040 return size; |
6041 } | |
6042 | |
6043 /* | |
6044 * Goto byte in buffer with offset 'cnt'. | |
6045 */ | |
6046 void | |
7827
41789f16d6b2
commit https://github.com/vim/vim/commit/52ea13da0fe86df1abf34de52841e367035170c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
6047 goto_byte(long cnt) |
7 | 6048 { |
6049 long boff = cnt; | |
6050 linenr_T lnum; | |
6051 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
6052 ml_flush_line(curbuf); // cached line may be dirty |
7 | 6053 setpcmark(); |
6054 if (boff) | |
6055 --boff; | |
6056 lnum = ml_find_line_or_offset(curbuf, (linenr_T)0, &boff); | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
6057 if (lnum < 1) // past the end |
7 | 6058 { |
6059 curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; | |
6060 curwin->w_curswant = MAXCOL; | |
6061 coladvance((colnr_T)MAXCOL); | |
6062 } | |
6063 else | |
6064 { | |
6065 curwin->w_cursor.lnum = lnum; | |
6066 curwin->w_cursor.col = (colnr_T)boff; | |
572 | 6067 curwin->w_cursor.coladd = 0; |
7 | 6068 curwin->w_set_curswant = TRUE; |
6069 } | |
6070 check_cursor(); | |
6071 | |
18800
f41b55f9357c
patch 8.1.2388: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18763
diff
changeset
|
6072 // Make sure the cursor is on the first byte of a multi-byte char. |
7 | 6073 if (has_mbyte) |
6074 mb_adjust_cursor(); | |
6075 } | |
6076 #endif |