comparison src/memline.c @ 625:81fe2ccc1207 v7.0179

updated for version 7.0179
author vimboss
date Thu, 12 Jan 2006 23:22:24 +0000
parents 66263e241ce3
children 52c87a746f4a
comparison
equal deleted inserted replaced
624:91e7d4a7b3b0 625:81fe2ccc1207
11 /* #define CHECK(c, s) if (c) EMSG(s) */ 11 /* #define CHECK(c, s) if (c) EMSG(s) */
12 #define CHECK(c, s) 12 #define CHECK(c, s)
13 13
14 /* 14 /*
15 * memline.c: Contains the functions for appending, deleting and changing the 15 * memline.c: Contains the functions for appending, deleting and changing the
16 * text lines. The memfile functions are used to store the information in blocks 16 * text lines. The memfile functions are used to store the information in
17 * of memory, backed up by a file. The structure of the information is a tree. 17 * blocks of memory, backed up by a file. The structure of the information is
18 * The root of the tree is a pointer block. The leaves of the tree are data 18 * a tree. The root of the tree is a pointer block. The leaves of the tree
19 * blocks. In between may be several layers of pointer blocks, forming branches. 19 * are data blocks. In between may be several layers of pointer blocks,
20 * forming branches.
20 * 21 *
21 * Three types of blocks are used: 22 * Three types of blocks are used:
22 * - Block nr 0 contains information for recovery 23 * - Block nr 0 contains information for recovery
23 * - Pointer blocks contain list of pointers to other blocks. 24 * - Pointer blocks contain list of pointers to other blocks.
24 * - Data blocks contain the actual text. 25 * - Data blocks contain the actual text.
167 short b0_magic_short; /* check for byte order of short */ 168 short b0_magic_short; /* check for byte order of short */
168 char_u b0_magic_char; /* check for last char */ 169 char_u b0_magic_char; /* check for last char */
169 }; 170 };
170 171
171 /* 172 /*
172 * Note: b0_fname and b0_flags are put at the end of the file name. For very 173 * Note: b0_dirty and b0_flags are put at the end of the file name. For very
173 * long file names in older versions of Vim they are invalid. 174 * long file names in older versions of Vim they are invalid.
174 * The 'fileencoding' comes before b0_flags, with a NUL in front. But only 175 * The 'fileencoding' comes before b0_flags, with a NUL in front. But only
175 * when there is room, for very long file names it's omitted. 176 * when there is room, for very long file names it's omitted.
176 */ 177 */
177 #define B0_DIRTY 0x55 178 #define B0_DIRTY 0x55
243 #ifdef FEAT_BYTEOFF 244 #ifdef FEAT_BYTEOFF
244 static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype)); 245 static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype));
245 #endif 246 #endif
246 247
247 /* 248 /*
248 * open a new memline for 'curbuf' 249 * Open a new memline for "buf".
249 * 250 *
250 * return FAIL for failure, OK otherwise 251 * Return FAIL for failure, OK otherwise.
251 */ 252 */
252 int 253 int
253 ml_open() 254 ml_open(buf)
255 buf_T *buf;
254 { 256 {
255 memfile_T *mfp; 257 memfile_T *mfp;
256 bhdr_T *hp = NULL; 258 bhdr_T *hp = NULL;
257 ZERO_BL *b0p; 259 ZERO_BL *b0p;
258 PTR_BL *pp; 260 PTR_BL *pp;
259 DATA_BL *dp; 261 DATA_BL *dp;
260 262
261 /* 263 /*
262 * init fields in memline struct 264 * init fields in memline struct
263 */ 265 */
264 curbuf->b_ml.ml_stack_size = 0; /* no stack yet */ 266 buf->b_ml.ml_stack_size = 0; /* no stack yet */
265 curbuf->b_ml.ml_stack = NULL; /* no stack yet */ 267 buf->b_ml.ml_stack = NULL; /* no stack yet */
266 curbuf->b_ml.ml_stack_top = 0; /* nothing in the stack */ 268 buf->b_ml.ml_stack_top = 0; /* nothing in the stack */
267 curbuf->b_ml.ml_locked = NULL; /* no cached block */ 269 buf->b_ml.ml_locked = NULL; /* no cached block */
268 curbuf->b_ml.ml_line_lnum = 0; /* no cached line */ 270 buf->b_ml.ml_line_lnum = 0; /* no cached line */
269 #ifdef FEAT_BYTEOFF 271 #ifdef FEAT_BYTEOFF
270 curbuf->b_ml.ml_chunksize = NULL; 272 buf->b_ml.ml_chunksize = NULL;
271 #endif 273 #endif
272 274
273 /* 275 /*
274 * When 'updatecount' is non-zero, flag that a swap file may be opened later. 276 * When 'updatecount' is non-zero swap file may be opened later.
275 */ 277 */
276 if (p_uc && curbuf->b_p_swf) 278 if (p_uc && buf->b_p_swf)
277 curbuf->b_may_swap = TRUE; 279 buf->b_may_swap = TRUE;
278 else 280 else
279 curbuf->b_may_swap = FALSE; 281 buf->b_may_swap = FALSE;
280 282
281 /* 283 /*
282 * Open the memfile. No swap file is created yet. 284 * Open the memfile. No swap file is created yet.
283 */ 285 */
284 mfp = mf_open(NULL, 0); 286 mfp = mf_open(NULL, 0);
285 if (mfp == NULL) 287 if (mfp == NULL)
286 goto error; 288 goto error;
287 289
288 curbuf->b_ml.ml_mfp = mfp; 290 buf->b_ml.ml_mfp = mfp;
289 curbuf->b_ml.ml_flags = ML_EMPTY; 291 buf->b_ml.ml_flags = ML_EMPTY;
290 curbuf->b_ml.ml_line_count = 1; 292 buf->b_ml.ml_line_count = 1;
291 #ifdef FEAT_LINEBREAK 293 #ifdef FEAT_LINEBREAK
292 curwin->w_nrwidth_line_count = 0; 294 curwin->w_nrwidth_line_count = 0;
293 #endif 295 #endif
294 296
295 #if defined(MSDOS) && !defined(DJGPP) 297 #if defined(MSDOS) && !defined(DJGPP)
296 /* for 16 bit MS-DOS create a swapfile now, because we run out of 298 /* for 16 bit MS-DOS create a swapfile now, because we run out of
297 * memory very quickly */ 299 * memory very quickly */
298 if (p_uc != 0) 300 if (p_uc != 0)
299 ml_open_file(curbuf); 301 ml_open_file(buf);
300 #endif 302 #endif
301 303
302 /* 304 /*
303 * fill block0 struct and write page 0 305 * fill block0 struct and write page 0
304 */ 306 */
311 } 313 }
312 b0p = (ZERO_BL *)(hp->bh_data); 314 b0p = (ZERO_BL *)(hp->bh_data);
313 315
314 b0p->b0_id[0] = BLOCK0_ID0; 316 b0p->b0_id[0] = BLOCK0_ID0;
315 b0p->b0_id[1] = BLOCK0_ID1; 317 b0p->b0_id[1] = BLOCK0_ID1;
316 b0p->b0_dirty = curbuf->b_changed ? B0_DIRTY : 0;
317 b0p->b0_flags = get_fileformat(curbuf) + 1;
318 b0p->b0_magic_long = (long)B0_MAGIC_LONG; 318 b0p->b0_magic_long = (long)B0_MAGIC_LONG;
319 b0p->b0_magic_int = (int)B0_MAGIC_INT; 319 b0p->b0_magic_int = (int)B0_MAGIC_INT;
320 b0p->b0_magic_short = (short)B0_MAGIC_SHORT; 320 b0p->b0_magic_short = (short)B0_MAGIC_SHORT;
321 b0p->b0_magic_char = B0_MAGIC_CHAR; 321 b0p->b0_magic_char = B0_MAGIC_CHAR;
322
323 STRNCPY(b0p->b0_version, "VIM ", 4); 322 STRNCPY(b0p->b0_version, "VIM ", 4);
324 STRNCPY(b0p->b0_version + 4, Version, 6); 323 STRNCPY(b0p->b0_version + 4, Version, 6);
325 set_b0_fname(b0p, curbuf);
326 long_to_char((long)mfp->mf_page_size, b0p->b0_page_size); 324 long_to_char((long)mfp->mf_page_size, b0p->b0_page_size);
327 (void)get_user_name(b0p->b0_uname, B0_UNAME_SIZE); 325
328 b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL; 326 if (!B_SPELL(buf))
329 mch_get_host_name(b0p->b0_hname, B0_HNAME_SIZE); 327 {
330 b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL; 328 b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
331 long_to_char(mch_get_pid(), b0p->b0_pid); 329 b0p->b0_flags = get_fileformat(buf) + 1;
330 set_b0_fname(b0p, buf);
331 (void)get_user_name(b0p->b0_uname, B0_UNAME_SIZE);
332 b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL;
333 mch_get_host_name(b0p->b0_hname, B0_HNAME_SIZE);
334 b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL;
335 long_to_char(mch_get_pid(), b0p->b0_pid);
336 }
332 337
333 /* 338 /*
334 * Always sync block number 0 to disk, so we can check the file name in 339 * Always sync block number 0 to disk, so we can check the file name in
335 * the swap file in findswapname(). Don't do this for help files though. 340 * the swap file in findswapname(). Don't do this for help files though
341 * and spell buffer though.
336 * Only works when there's a swapfile, otherwise it's done when the file 342 * Only works when there's a swapfile, otherwise it's done when the file
337 * is created. 343 * is created.
338 */ 344 */
339 mf_put(mfp, hp, TRUE, FALSE); 345 mf_put(mfp, hp, TRUE, FALSE);
340 if (!curbuf->b_help) 346 if (!buf->b_help && !B_SPELL(buf))
341 (void)mf_sync(mfp, 0); 347 (void)mf_sync(mfp, 0);
342 348
343 /* 349 /*
344 * fill in root pointer block and write page 1 350 * Fill in root pointer block and write page 1.
345 */ 351 */
346 if ((hp = ml_new_ptr(mfp)) == NULL) 352 if ((hp = ml_new_ptr(mfp)) == NULL)
347 goto error; 353 goto error;
348 if (hp->bh_bnum != 1) 354 if (hp->bh_bnum != 1)
349 { 355 {
350 EMSG(_("E298: Didn't get block nr 1?")); 356 EMSG(_("E298: Didn't get block nr 1?"));
356 pp->pb_pointer[0].pe_page_count = 1; 362 pp->pb_pointer[0].pe_page_count = 1;
357 pp->pb_pointer[0].pe_old_lnum = 1; 363 pp->pb_pointer[0].pe_old_lnum = 1;
358 pp->pb_pointer[0].pe_line_count = 1; /* line count after insertion */ 364 pp->pb_pointer[0].pe_line_count = 1; /* line count after insertion */
359 mf_put(mfp, hp, TRUE, FALSE); 365 mf_put(mfp, hp, TRUE, FALSE);
360 366
361 /* 367 /*
362 * allocate first data block and create an empty line 1. 368 * Allocate first data block and create an empty line 1.
363 */ 369 */
364 if ((hp = ml_new_data(mfp, FALSE, 1)) == NULL) 370 if ((hp = ml_new_data(mfp, FALSE, 1)) == NULL)
365 goto error; 371 goto error;
366 if (hp->bh_bnum != 2) 372 if (hp->bh_bnum != 2)
367 { 373 {
368 EMSG(_("E298: Didn't get block nr 2?")); 374 EMSG(_("E298: Didn't get block nr 2?"));
382 { 388 {
383 if (hp) 389 if (hp)
384 mf_put(mfp, hp, FALSE, FALSE); 390 mf_put(mfp, hp, FALSE, FALSE);
385 mf_close(mfp, TRUE); /* will also free(mfp->mf_fname) */ 391 mf_close(mfp, TRUE); /* will also free(mfp->mf_fname) */
386 } 392 }
387 curbuf->b_ml.ml_mfp = NULL; 393 buf->b_ml.ml_mfp = NULL;
388 return FAIL; 394 return FAIL;
389 } 395 }
390 396
391 /* 397 /*
392 * ml_setname() is called when the file name of "buf" has been changed. 398 * ml_setname() is called when the file name of "buf" has been changed.
515 char_u *dirp; 521 char_u *dirp;
516 522
517 mfp = buf->b_ml.ml_mfp; 523 mfp = buf->b_ml.ml_mfp;
518 if (mfp == NULL || mfp->mf_fd >= 0 || !buf->b_p_swf) 524 if (mfp == NULL || mfp->mf_fd >= 0 || !buf->b_p_swf)
519 return; /* nothing to do */ 525 return; /* nothing to do */
526
527 #ifdef FEAT_SYN_HL
528 /* For a spell buffer use a temp file name. */
529 if (buf->b_spell)
530 {
531 fname = vim_tempname('s');
532 if (fname != NULL)
533 (void)mf_open_file(mfp, fname); /* consumes fname! */
534 buf->b_may_swap = FALSE;
535 return;
536 }
537 #endif
520 538
521 /* 539 /*
522 * Try all directories in 'directory' option. 540 * Try all directories in 'directory' option.
523 */ 541 */
524 dirp = p_dir; 542 dirp = p_dir;
884 } 902 }
885 if (fname == NULL) 903 if (fname == NULL)
886 goto theend; /* out of memory */ 904 goto theend; /* out of memory */
887 905
888 /* When called from main() still need to initialize storage structure */ 906 /* When called from main() still need to initialize storage structure */
889 if (called_from_main && ml_open() == FAIL) 907 if (called_from_main && ml_open(curbuf) == FAIL)
890 getout(1); 908 getout(1);
891 909
892 /* 910 /*
893 * allocate a buffer structure (only the memline in it is really used) 911 * allocate a buffer structure (only the memline in it is really used)
894 */ 912 */
2097 2115
2098 if (curbuf->b_ml.ml_line_lnum != 0) 2116 if (curbuf->b_ml.ml_line_lnum != 0)
2099 ml_flush_line(curbuf); 2117 ml_flush_line(curbuf);
2100 return ml_append_int(curbuf, lnum, line, len, newfile, FALSE); 2118 return ml_append_int(curbuf, lnum, line, len, newfile, FALSE);
2101 } 2119 }
2120
2121 #if defined(FEAT_SYN_HL) || defined(PROTO)
2122 /*
2123 * Like ml_append() but for an arbitrary buffer. The buffer must already have
2124 * a memline.
2125 */
2126 int
2127 ml_append_buf(buf, lnum, line, len, newfile)
2128 buf_T *buf;
2129 linenr_T lnum; /* append after this line (can be 0) */
2130 char_u *line; /* text of the new line */
2131 colnr_T len; /* length of new line, including NUL, or 0 */
2132 int newfile; /* flag, see above */
2133 {
2134 if (buf->b_ml.ml_mfp == NULL)
2135 return FAIL;
2136
2137 if (buf->b_ml.ml_line_lnum != 0)
2138 ml_flush_line(buf);
2139 return ml_append_int(buf, lnum, line, len, newfile, FALSE);
2140 }
2141 #endif
2102 2142
2103 static int 2143 static int
2104 ml_append_int(buf, lnum, line, len, newfile, mark) 2144 ml_append_int(buf, lnum, line, len, newfile, mark)
2105 buf_T *buf; 2145 buf_T *buf;
2106 linenr_T lnum; /* append after this line (can be 0) */ 2146 linenr_T lnum; /* append after this line (can be 0) */
2597 #endif 2637 #endif
2598 return OK; 2638 return OK;
2599 } 2639 }
2600 2640
2601 /* 2641 /*
2602 * replace line lnum, with buffering, in current buffer 2642 * Replace line lnum, with buffering, in current buffer.
2603 * 2643 *
2604 * If copy is TRUE, make a copy of the line, otherwise the line has been 2644 * If copy is TRUE, make a copy of the line, otherwise the line has been
2605 * copied to allocated memory already. 2645 * copied to allocated memory already.
2606 * 2646 *
2607 * Check: The caller of this function should probably also call 2647 * Check: The caller of this function should probably also call
2641 2681
2642 return OK; 2682 return OK;
2643 } 2683 }
2644 2684
2645 /* 2685 /*
2646 * delete line 'lnum' 2686 * Delete line 'lnum' in the current buffer.
2647 * 2687 *
2648 * Check: The caller of this function should probably also call 2688 * Check: The caller of this function should probably also call
2649 * deleted_lines() after this. 2689 * deleted_lines() after this.
2650 * 2690 *
2651 * return FAIL for failure, OK otherwise 2691 * return FAIL for failure, OK otherwise
4112 } 4152 }
4113 else 4153 else
4114 #endif 4154 #endif
4115 { 4155 {
4116 MSG_PUTS("\n"); 4156 MSG_PUTS("\n");
4117 need_wait_return = TRUE; /* call wait_return later */ 4157 if (msg_silent == 0)
4158 /* call wait_return() later */
4159 need_wait_return = TRUE;
4118 } 4160 }
4119 4161
4120 #ifdef CREATE_DUMMY_FILE 4162 #ifdef CREATE_DUMMY_FILE
4121 /* Going to try another name, need the dummy file again. */ 4163 /* Going to try another name, need the dummy file again. */
4122 if (did_use_dummy) 4164 if (did_use_dummy)