Mercurial > hg > xemacs-beta
comparison src/insdel.c @ 428:3ecd8885ac67 r21-2-22
Import from CVS: tag r21-2-22
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:28:15 +0200 |
parents | |
children | 84b14dcb0985 |
comparison
equal
deleted
inserted
replaced
427:0a0253eac470 | 428:3ecd8885ac67 |
---|---|
1 /* Buffer insertion/deletion and gap motion for XEmacs. | |
2 Copyright (C) 1985, 1986, 1991, 1992, 1993, 1994, 1995 | |
3 Free Software Foundation, Inc. | |
4 Copyright (C) 1995 Sun Microsystems, Inc. | |
5 | |
6 This file is part of XEmacs. | |
7 | |
8 XEmacs is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
10 Free Software Foundation; either version 2, or (at your option) any | |
11 later version. | |
12 | |
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with XEmacs; see the file COPYING. If not, write to | |
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
21 Boston, MA 02111-1307, USA. */ | |
22 | |
23 /* Synched up with: Mule 2.0, FSF 19.30. Diverges significantly. */ | |
24 | |
25 /* This file has been Mule-ized. */ | |
26 | |
27 /* Overhauled by Ben Wing, December 1994, for Mule implementation. */ | |
28 | |
29 /* | |
30 There are three possible ways to specify positions in a buffer. All | |
31 of these are one-based: the beginning of the buffer is position or | |
32 index 1, and 0 is not a valid position. | |
33 | |
34 As a "buffer position" (typedef Bufpos): | |
35 | |
36 This is an index specifying an offset in characters from the | |
37 beginning of the buffer. Note that buffer positions are | |
38 logically *between* characters, not on a character. The | |
39 difference between two buffer positions specifies the number of | |
40 characters between those positions. Buffer positions are the | |
41 only kind of position externally visible to the user. | |
42 | |
43 As a "byte index" (typedef Bytind): | |
44 | |
45 This is an index over the bytes used to represent the characters | |
46 in the buffer. If there is no Mule support, this is identical | |
47 to a buffer position, because each character is represented | |
48 using one byte. However, with Mule support, many characters | |
49 require two or more bytes for their representation, and so a | |
50 byte index may be greater than the corresponding buffer | |
51 position. | |
52 | |
53 As a "memory index" (typedef Memind): | |
54 | |
55 This is the byte index adjusted for the gap. For positions | |
56 before the gap, this is identical to the byte index. For | |
57 positions after the gap, this is the byte index plus the gap | |
58 size. There are two possible memory indices for the gap | |
59 position; the memory index at the beginning of the gap should | |
60 always be used, except in code that deals with manipulating the | |
61 gap, where both indices may be seen. The address of the | |
62 character "at" (i.e. following) a particular position can be | |
63 obtained from the formula | |
64 | |
65 buffer_start_address + memory_index(position) - 1 | |
66 | |
67 except in the case of characters at the gap position. | |
68 | |
69 Other typedefs: | |
70 =============== | |
71 | |
72 Emchar: | |
73 ------- | |
74 This typedef represents a single Emacs character, which can be | |
75 ASCII, ISO-8859, or some extended character, as would typically | |
76 be used for Kanji. Note that the representation of a character | |
77 as an Emchar is *not* the same as the representation of that | |
78 same character in a string; thus, you cannot do the standard | |
79 C trick of passing a pointer to a character to a function that | |
80 expects a string. | |
81 | |
82 An Emchar takes up 19 bits of representation and (for code | |
83 compatibility and such) is compatible with an int. This | |
84 representation is visible on the Lisp level. The important | |
85 characteristics of the Emchar representation are | |
86 | |
87 -- values 0x00 - 0x7f represent ASCII. | |
88 -- values 0x80 - 0xff represent the right half of ISO-8859-1. | |
89 -- values 0x100 and up represent all other characters. | |
90 | |
91 This means that Emchar values are upwardly compatible with | |
92 the standard 8-bit representation of ASCII/ISO-8859-1. | |
93 | |
94 Bufbyte: | |
95 -------- | |
96 The data in a buffer or string is logically made up of Bufbyte | |
97 objects, where a Bufbyte takes up the same amount of space as a | |
98 char. (It is declared differently, though, to catch invalid | |
99 usages.) Strings stored using Bufbytes are said to be in | |
100 "internal format". The important characteristics of internal | |
101 format are | |
102 | |
103 -- ASCII characters are represented as a single Bufbyte, | |
104 in the range 0 - 0x7f. | |
105 -- All other characters are represented as a Bufbyte in | |
106 the range 0x80 - 0x9f followed by one or more Bufbytes | |
107 in the range 0xa0 to 0xff. | |
108 | |
109 This leads to a number of desirable properties: | |
110 | |
111 -- Given the position of the beginning of a character, | |
112 you can find the beginning of the next or previous | |
113 character in constant time. | |
114 -- When searching for a substring or an ASCII character | |
115 within the string, you need merely use standard | |
116 searching routines. | |
117 | |
118 array of char: | |
119 -------------- | |
120 Strings that go in or out of Emacs are in "external format", | |
121 typedef'ed as an array of char or a char *. There is more | |
122 than one external format (JIS, EUC, etc.) but they all | |
123 have similar properties. They are modal encodings, | |
124 which is to say that the meaning of particular bytes is | |
125 not fixed but depends on what "mode" the string is currently | |
126 in (e.g. bytes in the range 0 - 0x7f might be | |
127 interpreted as ASCII, or as Hiragana, or as 2-byte Kanji, | |
128 depending on the current mode). The mode starts out in | |
129 ASCII/ISO-8859-1 and is switched using escape sequences -- | |
130 for example, in the JIS encoding, 'ESC $ B' switches to a | |
131 mode where pairs of bytes in the range 0 - 0x7f | |
132 are interpreted as Kanji characters. | |
133 | |
134 External-formatted data is generally desirable for passing | |
135 data between programs because it is upwardly compatible | |
136 with standard ASCII/ISO-8859-1 strings and may require | |
137 less space than internal encodings such as the one | |
138 described above. In addition, some encodings (e.g. JIS) | |
139 keep all characters (except the ESC used to switch modes) | |
140 in the printing ASCII range 0x20 - 0x7e, which results in | |
141 a much higher probability that the data will avoid being | |
142 garbled in transmission. Externally-formatted data is | |
143 generally not very convenient to work with, however, and | |
144 for this reason is usually converted to internal format | |
145 before any work is done on the string. | |
146 | |
147 NOTE: filenames need to be in external format so that | |
148 ISO-8859-1 characters come out correctly. | |
149 | |
150 Charcount: | |
151 ---------- | |
152 This typedef represents a count of characters, such as | |
153 a character offset into a string or the number of | |
154 characters between two positions in a buffer. The | |
155 difference between two Bufpos's is a Charcount, and | |
156 character positions in a string are represented using | |
157 a Charcount. | |
158 | |
159 Bytecount: | |
160 ---------- | |
161 Similar to a Charcount but represents a count of bytes. | |
162 The difference between two Bytind's is a Bytecount. | |
163 | |
164 | |
165 Usage of the various representations: | |
166 ===================================== | |
167 | |
168 Memory indices are used in low-level functions in insdel.c and for | |
169 extent endpoints and marker positions. The reason for this is that | |
170 this way, the extents and markers don't need to be updated for most | |
171 insertions, which merely shrink the gap and don't move any | |
172 characters around in memory. | |
173 | |
174 (The beginning-of-gap memory index simplifies insertions w.r.t. | |
175 markers, because text usually gets inserted after markers. For | |
176 extents, it is merely for consistency, because text can get | |
177 inserted either before or after an extent's endpoint depending on | |
178 the open/closedness of the endpoint.) | |
179 | |
180 Byte indices are used in other code that needs to be fast, | |
181 such as the searching, redisplay, and extent-manipulation code. | |
182 | |
183 Buffer positions are used in all other code. This is because this | |
184 representation is easiest to work with (especially since Lisp | |
185 code always uses buffer positions), necessitates the fewest | |
186 changes to existing code, and is the safest (e.g. if the text gets | |
187 shifted underneath a buffer position, it will still point to a | |
188 character; if text is shifted under a byte index, it might point | |
189 to the middle of a character, which would be bad). | |
190 | |
191 Similarly, Charcounts are used in all code that deals with strings | |
192 except for code that needs to be fast, which used Bytecounts. | |
193 | |
194 Strings are always passed around internally using internal format. | |
195 Conversions between external format are performed at the time | |
196 that the data goes in or out of Emacs. | |
197 | |
198 Working with the various representations: | |
199 ========================================= */ | |
200 | |
201 #include <config.h> | |
202 #include "lisp.h" | |
203 #include <limits.h> | |
204 | |
205 #include "buffer.h" | |
206 #include "device.h" | |
207 #include "frame.h" | |
208 #include "extents.h" | |
209 #include "insdel.h" | |
210 #include "lstream.h" | |
211 #include "redisplay.h" | |
212 #include "line-number.h" | |
213 | |
214 /* We write things this way because it's very important the | |
215 MAX_BYTIND_GAP_SIZE_3 is a multiple of 3. (As it happens, | |
216 65535 is a multiple of 3, but this may not always be the | |
217 case.) */ | |
218 | |
219 #define MAX_BUFPOS_GAP_SIZE_3 (65535/3) | |
220 #define MAX_BYTIND_GAP_SIZE_3 (3 * MAX_BUFPOS_GAP_SIZE_3) | |
221 | |
222 short three_to_one_table[1 + MAX_BYTIND_GAP_SIZE_3]; | |
223 | |
224 /* Various macros modelled along the lines of those in buffer.h. | |
225 Purposefully omitted from buffer.h because files other than this | |
226 one should not be using them. */ | |
227 | |
228 /* Address of beginning of buffer. This is an lvalue because | |
229 BUFFER_ALLOC needs it to be. */ | |
230 #define BUF_BEG_ADDR(buf) ((buf)->text->beg) | |
231 | |
232 /* Set the address of beginning of buffer. */ | |
233 #define SET_BUF_BEG_ADDR(buf, addr) do { (buf)->text->beg = (addr); } while (0) | |
234 | |
235 /* Gap size. */ | |
236 #define BUF_GAP_SIZE(buf) ((buf)->text->gap_size + 0) | |
237 #define BUF_END_GAP_SIZE(buf) ((buf)->text->end_gap_size + 0) | |
238 /* Set gap size. */ | |
239 #define SET_BUF_GAP_SIZE(buf, value) \ | |
240 do { (buf)->text->gap_size = (value); } while (0) | |
241 #define SET_BUF_END_GAP_SIZE(buf, value) \ | |
242 do { (buf)->text->end_gap_size = (value); } while (0) | |
243 | |
244 /* Gap location. */ | |
245 #define BI_BUF_GPT(buf) ((buf)->text->gpt + 0) | |
246 #define BUF_GPT_ADDR(buf) (BUF_BEG_ADDR (buf) + BI_BUF_GPT (buf) - 1) | |
247 | |
248 /* Set gap location. */ | |
249 #define SET_BI_BUF_GPT(buf, value) do { (buf)->text->gpt = (value); } while (0) | |
250 | |
251 /* Set end of buffer. */ | |
252 #define SET_BOTH_BUF_Z(buf, val, bival) \ | |
253 do \ | |
254 { \ | |
255 (buf)->text->z = (bival); \ | |
256 (buf)->text->bufz = (val); \ | |
257 } while (0) | |
258 | |
259 /* Under Mule, we maintain two sentinels in the buffer: one at the | |
260 beginning of the gap, and one at the end of the buffer. This | |
261 allows us to move forward, examining bytes looking for the | |
262 end of a character, and not worry about running off the end. | |
263 We do not need corresponding sentinels when moving backwards | |
264 because we do not have to look past the beginning of a character | |
265 to find the beginning of the character. | |
266 | |
267 Every time we change the beginning of the gap, we have to | |
268 call SET_GAP_SENTINEL(). | |
269 | |
270 Every time we change the total size (characters plus gap) | |
271 of the buffer, we have to call SET_END_SENTINEL(). | |
272 */ | |
273 | |
274 | |
275 #ifdef MULE | |
276 # define GAP_CAN_HOLD_SIZE_P(buf, len) (BUF_GAP_SIZE (buf) >= (len) + 1) | |
277 # define SET_GAP_SENTINEL(buf) (*BUF_GPT_ADDR (buf) = 0) | |
278 # define BUF_END_SENTINEL_SIZE 1 | |
279 # define SET_END_SENTINEL(buf) \ | |
280 (*(BUF_BEG_ADDR (buf) + BUF_GAP_SIZE (buf) + BI_BUF_Z (buf) - 1) = 0) | |
281 #else | |
282 # define GAP_CAN_HOLD_SIZE_P(buf, len) (BUF_GAP_SIZE (buf) >= (len)) | |
283 # define SET_GAP_SENTINEL(buf) | |
284 # define BUF_END_SENTINEL_SIZE 0 | |
285 # define SET_END_SENTINEL(buf) | |
286 #endif | |
287 | |
288 | |
289 /************************************************************************/ | |
290 /* Charcount/Bytecount conversion */ | |
291 /************************************************************************/ | |
292 | |
293 /* Optimization. Do it. Live it. Love it. */ | |
294 | |
295 #ifdef MULE | |
296 | |
297 /* We include the basic functions here that require no specific | |
298 knowledge of how data is Mule-encoded into a buffer other | |
299 than the basic (00 - 7F), (80 - 9F), (A0 - FF) scheme. | |
300 Anything that requires more specific knowledge goes into | |
301 mule-charset.c. */ | |
302 | |
303 /* Given a pointer to a text string and a length in bytes, return | |
304 the equivalent length in characters. */ | |
305 | |
306 Charcount | |
307 bytecount_to_charcount (CONST Bufbyte *ptr, Bytecount len) | |
308 { | |
309 Charcount count = 0; | |
310 CONST Bufbyte *end = ptr + len; | |
311 | |
312 #if (LONGBITS == 32 || LONGBITS == 64) | |
313 | |
314 # if (LONGBITS == 32) | |
315 # define LONG_BYTES 4 | |
316 # define ALIGN_MASK 0xFFFFFFFCU | |
317 # define HIGH_BIT_MASK 0x80808080U | |
318 # else | |
319 # define LONG_BYTES 8 | |
320 # define ALIGN_MASK 0xFFFFFFFFFFFFFFF8UL | |
321 /* I had a dream, I was being overrun with early Intel processors ... */ | |
322 # define HIGH_BIT_MASK 0x8080808080808080UL | |
323 # endif | |
324 | |
325 /* When we have a large number of bytes to scan, we can be trickier | |
326 and significantly faster by scanning them in chunks of the CPU word | |
327 size (assuming that they're all ASCII -- we cut out as soon as | |
328 we find something non-ASCII). */ | |
329 if (len >= 12) | |
330 { | |
331 /* Determine the section in the middle of the string that's | |
332 amenable to this treatment. Everything has to be aligned | |
333 on CPU word boundaries. */ | |
334 CONST Bufbyte *aligned_ptr = | |
335 (CONST Bufbyte *) (((unsigned long) (ptr + LONG_BYTES - 1)) & | |
336 ALIGN_MASK); | |
337 CONST Bufbyte *aligned_end = | |
338 (CONST Bufbyte *) (((unsigned long) end) & ALIGN_MASK); | |
339 | |
340 /* Handle unaligned stuff at the beginning. */ | |
341 while (ptr < aligned_ptr) | |
342 { | |
343 if (!BYTE_ASCII_P (*ptr)) | |
344 goto bail; | |
345 count++, ptr++; | |
346 } | |
347 /* Now do it. */ | |
348 while (ptr < aligned_end) | |
349 { | |
350 | |
351 if ((* (unsigned long *) ptr) & HIGH_BIT_MASK) | |
352 goto bail; | |
353 ptr += LONG_BYTES; | |
354 count += LONG_BYTES; | |
355 } | |
356 } | |
357 | |
358 #endif /* LONGBITS == 32 || LONGBITS == 64 */ | |
359 | |
360 bail: | |
361 while (ptr < end) | |
362 { | |
363 count++; | |
364 INC_CHARPTR (ptr); | |
365 } | |
366 #ifdef ERROR_CHECK_BUFPOS | |
367 /* Bomb out if the specified substring ends in the middle | |
368 of a character. Note that we might have already gotten | |
369 a core dump above from an invalid reference, but at least | |
370 we will get no farther than here. */ | |
371 assert (ptr == end); | |
372 #endif | |
373 | |
374 return count; | |
375 } | |
376 | |
377 /* Given a pointer to a text string and a length in characters, return | |
378 the equivalent length in bytes. */ | |
379 | |
380 Bytecount | |
381 charcount_to_bytecount (CONST Bufbyte *ptr, Charcount len) | |
382 { | |
383 CONST Bufbyte *newptr = ptr; | |
384 | |
385 while (len > 0) | |
386 { | |
387 INC_CHARPTR (newptr); | |
388 len--; | |
389 } | |
390 return newptr - ptr; | |
391 } | |
392 | |
393 /* The next two functions are the actual meat behind the | |
394 bufpos-to-bytind and bytind-to-bufpos conversions. Currently | |
395 the method they use is fairly unsophisticated; see buffer.h. | |
396 | |
397 Note that bufpos_to_bytind_func() is probably the most-called | |
398 function in all of XEmacs. Therefore, it must be FAST FAST FAST. | |
399 This is the reason why so much of the code is duplicated. | |
400 | |
401 Similar considerations apply to bytind_to_bufpos_func(), although | |
402 less so because the function is not called so often. | |
403 | |
404 #### At some point this should use a more sophisticated method; | |
405 see buffer.h. */ | |
406 | |
407 static int not_very_random_number; | |
408 | |
409 Bytind | |
410 bufpos_to_bytind_func (struct buffer *buf, Bufpos x) | |
411 { | |
412 Bufpos bufmin; | |
413 Bufpos bufmax; | |
414 Bytind bytmin; | |
415 Bytind bytmax; | |
416 int size; | |
417 int forward_p; | |
418 Bytind retval; | |
419 int diff_so_far; | |
420 int add_to_cache = 0; | |
421 | |
422 /* Check for some cached positions, for speed. */ | |
423 if (x == BUF_PT (buf)) | |
424 return BI_BUF_PT (buf); | |
425 if (x == BUF_ZV (buf)) | |
426 return BI_BUF_ZV (buf); | |
427 if (x == BUF_BEGV (buf)) | |
428 return BI_BUF_BEGV (buf); | |
429 | |
430 bufmin = buf->text->mule_bufmin; | |
431 bufmax = buf->text->mule_bufmax; | |
432 bytmin = buf->text->mule_bytmin; | |
433 bytmax = buf->text->mule_bytmax; | |
434 size = (1 << buf->text->mule_shifter) + !!buf->text->mule_three_p; | |
435 | |
436 /* The basic idea here is that we shift the "known region" up or down | |
437 until it overlaps the specified position. We do this by moving | |
438 the upper bound of the known region up one character at a time, | |
439 and moving the lower bound of the known region up as necessary | |
440 when the size of the character just seen changes. | |
441 | |
442 We optimize this, however, by first shifting the known region to | |
443 one of the cached points if it's close by. (We don't check BEG or | |
444 Z, even though they're cached; most of the time these will be the | |
445 same as BEGV and ZV, and when they're not, they're not likely | |
446 to be used.) */ | |
447 | |
448 if (x > bufmax) | |
449 { | |
450 Bufpos diffmax = x - bufmax; | |
451 Bufpos diffpt = x - BUF_PT (buf); | |
452 Bufpos diffzv = BUF_ZV (buf) - x; | |
453 /* #### This value could stand some more exploration. */ | |
454 Charcount heuristic_hack = (bufmax - bufmin) >> 2; | |
455 | |
456 /* Check if the position is closer to PT or ZV than to the | |
457 end of the known region. */ | |
458 | |
459 if (diffpt < 0) | |
460 diffpt = -diffpt; | |
461 if (diffzv < 0) | |
462 diffzv = -diffzv; | |
463 | |
464 /* But also implement a heuristic that favors the known region | |
465 over PT or ZV. The reason for this is that switching to | |
466 PT or ZV will wipe out the knowledge in the known region, | |
467 which might be annoying if the known region is large and | |
468 PT or ZV is not that much closer than the end of the known | |
469 region. */ | |
470 | |
471 diffzv += heuristic_hack; | |
472 diffpt += heuristic_hack; | |
473 if (diffpt < diffmax && diffpt <= diffzv) | |
474 { | |
475 bufmax = bufmin = BUF_PT (buf); | |
476 bytmax = bytmin = BI_BUF_PT (buf); | |
477 /* We set the size to 1 even though it doesn't really | |
478 matter because the new known region contains no | |
479 characters. We do this because this is the most | |
480 likely size of the characters around the new known | |
481 region, and we avoid potential yuckiness that is | |
482 done when size == 3. */ | |
483 size = 1; | |
484 } | |
485 if (diffzv < diffmax) | |
486 { | |
487 bufmax = bufmin = BUF_ZV (buf); | |
488 bytmax = bytmin = BI_BUF_ZV (buf); | |
489 size = 1; | |
490 } | |
491 } | |
492 #ifdef ERROR_CHECK_BUFPOS | |
493 else if (x >= bufmin) | |
494 abort (); | |
495 #endif | |
496 else | |
497 { | |
498 Bufpos diffmin = bufmin - x; | |
499 Bufpos diffpt = BUF_PT (buf) - x; | |
500 Bufpos diffbegv = x - BUF_BEGV (buf); | |
501 /* #### This value could stand some more exploration. */ | |
502 Charcount heuristic_hack = (bufmax - bufmin) >> 2; | |
503 | |
504 if (diffpt < 0) | |
505 diffpt = -diffpt; | |
506 if (diffbegv < 0) | |
507 diffbegv = -diffbegv; | |
508 | |
509 /* But also implement a heuristic that favors the known region -- | |
510 see above. */ | |
511 | |
512 diffbegv += heuristic_hack; | |
513 diffpt += heuristic_hack; | |
514 | |
515 if (diffpt < diffmin && diffpt <= diffbegv) | |
516 { | |
517 bufmax = bufmin = BUF_PT (buf); | |
518 bytmax = bytmin = BI_BUF_PT (buf); | |
519 /* We set the size to 1 even though it doesn't really | |
520 matter because the new known region contains no | |
521 characters. We do this because this is the most | |
522 likely size of the characters around the new known | |
523 region, and we avoid potential yuckiness that is | |
524 done when size == 3. */ | |
525 size = 1; | |
526 } | |
527 if (diffbegv < diffmin) | |
528 { | |
529 bufmax = bufmin = BUF_BEGV (buf); | |
530 bytmax = bytmin = BI_BUF_BEGV (buf); | |
531 size = 1; | |
532 } | |
533 } | |
534 | |
535 diff_so_far = x > bufmax ? x - bufmax : bufmin - x; | |
536 if (diff_so_far > 50) | |
537 { | |
538 /* If we have to move more than a certain amount, then look | |
539 into our cache. */ | |
540 int minval = INT_MAX; | |
541 int found = 0; | |
542 int i; | |
543 | |
544 add_to_cache = 1; | |
545 /* I considered keeping the positions ordered. This would speed | |
546 up this loop, but updating the cache would take longer, so | |
547 it doesn't seem like it would really matter. */ | |
548 for (i = 0; i < 16; i++) | |
549 { | |
550 int diff = buf->text->mule_bufpos_cache[i] - x; | |
551 | |
552 if (diff < 0) | |
553 diff = -diff; | |
554 if (diff < minval) | |
555 { | |
556 minval = diff; | |
557 found = i; | |
558 } | |
559 } | |
560 | |
561 if (minval < diff_so_far) | |
562 { | |
563 bufmax = bufmin = buf->text->mule_bufpos_cache[found]; | |
564 bytmax = bytmin = buf->text->mule_bytind_cache[found]; | |
565 size = 1; | |
566 } | |
567 } | |
568 | |
569 /* It's conceivable that the caching above could lead to X being | |
570 the same as one of the range edges. */ | |
571 if (x >= bufmax) | |
572 { | |
573 Bytind newmax; | |
574 Bytecount newsize; | |
575 | |
576 forward_p = 1; | |
577 while (x > bufmax) | |
578 { | |
579 newmax = bytmax; | |
580 | |
581 INC_BYTIND (buf, newmax); | |
582 newsize = newmax - bytmax; | |
583 if (newsize != size) | |
584 { | |
585 bufmin = bufmax; | |
586 bytmin = bytmax; | |
587 size = newsize; | |
588 } | |
589 bytmax = newmax; | |
590 bufmax++; | |
591 } | |
592 retval = bytmax; | |
593 | |
594 /* #### Should go past the found location to reduce the number | |
595 of times that this function is called */ | |
596 } | |
597 else /* x < bufmin */ | |
598 { | |
599 Bytind newmin; | |
600 Bytecount newsize; | |
601 | |
602 forward_p = 0; | |
603 while (x < bufmin) | |
604 { | |
605 newmin = bytmin; | |
606 | |
607 DEC_BYTIND (buf, newmin); | |
608 newsize = bytmin - newmin; | |
609 if (newsize != size) | |
610 { | |
611 bufmax = bufmin; | |
612 bytmax = bytmin; | |
613 size = newsize; | |
614 } | |
615 bytmin = newmin; | |
616 bufmin--; | |
617 } | |
618 retval = bytmin; | |
619 | |
620 /* #### Should go past the found location to reduce the number | |
621 of times that this function is called | |
622 */ | |
623 } | |
624 | |
625 /* If size is three, than we have to max sure that the range we | |
626 discovered isn't too large, because we use a fixed-length | |
627 table to divide by 3. */ | |
628 | |
629 if (size == 3) | |
630 { | |
631 int gap = bytmax - bytmin; | |
632 buf->text->mule_three_p = 1; | |
633 buf->text->mule_shifter = 1; | |
634 | |
635 if (gap > MAX_BYTIND_GAP_SIZE_3) | |
636 { | |
637 if (forward_p) | |
638 { | |
639 bytmin = bytmax - MAX_BYTIND_GAP_SIZE_3; | |
640 bufmin = bufmax - MAX_BUFPOS_GAP_SIZE_3; | |
641 } | |
642 else | |
643 { | |
644 bytmax = bytmin + MAX_BYTIND_GAP_SIZE_3; | |
645 bufmax = bufmin + MAX_BUFPOS_GAP_SIZE_3; | |
646 } | |
647 } | |
648 } | |
649 else | |
650 { | |
651 buf->text->mule_three_p = 0; | |
652 if (size == 4) | |
653 buf->text->mule_shifter = 2; | |
654 else | |
655 buf->text->mule_shifter = size - 1; | |
656 } | |
657 | |
658 buf->text->mule_bufmin = bufmin; | |
659 buf->text->mule_bufmax = bufmax; | |
660 buf->text->mule_bytmin = bytmin; | |
661 buf->text->mule_bytmax = bytmax; | |
662 | |
663 if (add_to_cache) | |
664 { | |
665 int replace_loc; | |
666 | |
667 /* We throw away a "random" cached value and replace it with | |
668 the new value. It doesn't actually have to be very random | |
669 at all, just evenly distributed. | |
670 | |
671 #### It would be better to use a least-recently-used algorithm | |
672 or something that tries to space things out, but I'm not sure | |
673 it's worth it to go to the trouble of maintaining that. */ | |
674 not_very_random_number += 621; | |
675 replace_loc = not_very_random_number & 15; | |
676 buf->text->mule_bufpos_cache[replace_loc] = x; | |
677 buf->text->mule_bytind_cache[replace_loc] = retval; | |
678 } | |
679 | |
680 return retval; | |
681 } | |
682 | |
683 /* The logic in this function is almost identical to the logic in | |
684 the previous function. */ | |
685 | |
686 Bufpos | |
687 bytind_to_bufpos_func (struct buffer *buf, Bytind x) | |
688 { | |
689 Bufpos bufmin; | |
690 Bufpos bufmax; | |
691 Bytind bytmin; | |
692 Bytind bytmax; | |
693 int size; | |
694 int forward_p; | |
695 Bufpos retval; | |
696 int diff_so_far; | |
697 int add_to_cache = 0; | |
698 | |
699 /* Check for some cached positions, for speed. */ | |
700 if (x == BI_BUF_PT (buf)) | |
701 return BUF_PT (buf); | |
702 if (x == BI_BUF_ZV (buf)) | |
703 return BUF_ZV (buf); | |
704 if (x == BI_BUF_BEGV (buf)) | |
705 return BUF_BEGV (buf); | |
706 | |
707 bufmin = buf->text->mule_bufmin; | |
708 bufmax = buf->text->mule_bufmax; | |
709 bytmin = buf->text->mule_bytmin; | |
710 bytmax = buf->text->mule_bytmax; | |
711 size = (1 << buf->text->mule_shifter) + !!buf->text->mule_three_p; | |
712 | |
713 /* The basic idea here is that we shift the "known region" up or down | |
714 until it overlaps the specified position. We do this by moving | |
715 the upper bound of the known region up one character at a time, | |
716 and moving the lower bound of the known region up as necessary | |
717 when the size of the character just seen changes. | |
718 | |
719 We optimize this, however, by first shifting the known region to | |
720 one of the cached points if it's close by. (We don't check BI_BEG or | |
721 BI_Z, even though they're cached; most of the time these will be the | |
722 same as BI_BEGV and BI_ZV, and when they're not, they're not likely | |
723 to be used.) */ | |
724 | |
725 if (x > bytmax) | |
726 { | |
727 Bytind diffmax = x - bytmax; | |
728 Bytind diffpt = x - BI_BUF_PT (buf); | |
729 Bytind diffzv = BI_BUF_ZV (buf) - x; | |
730 /* #### This value could stand some more exploration. */ | |
731 Bytecount heuristic_hack = (bytmax - bytmin) >> 2; | |
732 | |
733 /* Check if the position is closer to PT or ZV than to the | |
734 end of the known region. */ | |
735 | |
736 if (diffpt < 0) | |
737 diffpt = -diffpt; | |
738 if (diffzv < 0) | |
739 diffzv = -diffzv; | |
740 | |
741 /* But also implement a heuristic that favors the known region | |
742 over BI_PT or BI_ZV. The reason for this is that switching to | |
743 BI_PT or BI_ZV will wipe out the knowledge in the known region, | |
744 which might be annoying if the known region is large and | |
745 BI_PT or BI_ZV is not that much closer than the end of the known | |
746 region. */ | |
747 | |
748 diffzv += heuristic_hack; | |
749 diffpt += heuristic_hack; | |
750 if (diffpt < diffmax && diffpt <= diffzv) | |
751 { | |
752 bufmax = bufmin = BUF_PT (buf); | |
753 bytmax = bytmin = BI_BUF_PT (buf); | |
754 /* We set the size to 1 even though it doesn't really | |
755 matter because the new known region contains no | |
756 characters. We do this because this is the most | |
757 likely size of the characters around the new known | |
758 region, and we avoid potential yuckiness that is | |
759 done when size == 3. */ | |
760 size = 1; | |
761 } | |
762 if (diffzv < diffmax) | |
763 { | |
764 bufmax = bufmin = BUF_ZV (buf); | |
765 bytmax = bytmin = BI_BUF_ZV (buf); | |
766 size = 1; | |
767 } | |
768 } | |
769 #ifdef ERROR_CHECK_BUFPOS | |
770 else if (x >= bytmin) | |
771 abort (); | |
772 #endif | |
773 else | |
774 { | |
775 Bytind diffmin = bytmin - x; | |
776 Bytind diffpt = BI_BUF_PT (buf) - x; | |
777 Bytind diffbegv = x - BI_BUF_BEGV (buf); | |
778 /* #### This value could stand some more exploration. */ | |
779 Bytecount heuristic_hack = (bytmax - bytmin) >> 2; | |
780 | |
781 if (diffpt < 0) | |
782 diffpt = -diffpt; | |
783 if (diffbegv < 0) | |
784 diffbegv = -diffbegv; | |
785 | |
786 /* But also implement a heuristic that favors the known region -- | |
787 see above. */ | |
788 | |
789 diffbegv += heuristic_hack; | |
790 diffpt += heuristic_hack; | |
791 | |
792 if (diffpt < diffmin && diffpt <= diffbegv) | |
793 { | |
794 bufmax = bufmin = BUF_PT (buf); | |
795 bytmax = bytmin = BI_BUF_PT (buf); | |
796 /* We set the size to 1 even though it doesn't really | |
797 matter because the new known region contains no | |
798 characters. We do this because this is the most | |
799 likely size of the characters around the new known | |
800 region, and we avoid potential yuckiness that is | |
801 done when size == 3. */ | |
802 size = 1; | |
803 } | |
804 if (diffbegv < diffmin) | |
805 { | |
806 bufmax = bufmin = BUF_BEGV (buf); | |
807 bytmax = bytmin = BI_BUF_BEGV (buf); | |
808 size = 1; | |
809 } | |
810 } | |
811 | |
812 diff_so_far = x > bytmax ? x - bytmax : bytmin - x; | |
813 if (diff_so_far > 50) | |
814 { | |
815 /* If we have to move more than a certain amount, then look | |
816 into our cache. */ | |
817 int minval = INT_MAX; | |
818 int found = 0; | |
819 int i; | |
820 | |
821 add_to_cache = 1; | |
822 /* I considered keeping the positions ordered. This would speed | |
823 up this loop, but updating the cache would take longer, so | |
824 it doesn't seem like it would really matter. */ | |
825 for (i = 0; i < 16; i++) | |
826 { | |
827 int diff = buf->text->mule_bytind_cache[i] - x; | |
828 | |
829 if (diff < 0) | |
830 diff = -diff; | |
831 if (diff < minval) | |
832 { | |
833 minval = diff; | |
834 found = i; | |
835 } | |
836 } | |
837 | |
838 if (minval < diff_so_far) | |
839 { | |
840 bufmax = bufmin = buf->text->mule_bufpos_cache[found]; | |
841 bytmax = bytmin = buf->text->mule_bytind_cache[found]; | |
842 size = 1; | |
843 } | |
844 } | |
845 | |
846 /* It's conceivable that the caching above could lead to X being | |
847 the same as one of the range edges. */ | |
848 if (x >= bytmax) | |
849 { | |
850 Bytind newmax; | |
851 Bytecount newsize; | |
852 | |
853 forward_p = 1; | |
854 while (x > bytmax) | |
855 { | |
856 newmax = bytmax; | |
857 | |
858 INC_BYTIND (buf, newmax); | |
859 newsize = newmax - bytmax; | |
860 if (newsize != size) | |
861 { | |
862 bufmin = bufmax; | |
863 bytmin = bytmax; | |
864 size = newsize; | |
865 } | |
866 bytmax = newmax; | |
867 bufmax++; | |
868 } | |
869 retval = bufmax; | |
870 | |
871 /* #### Should go past the found location to reduce the number | |
872 of times that this function is called */ | |
873 } | |
874 else /* x <= bytmin */ | |
875 { | |
876 Bytind newmin; | |
877 Bytecount newsize; | |
878 | |
879 forward_p = 0; | |
880 while (x < bytmin) | |
881 { | |
882 newmin = bytmin; | |
883 | |
884 DEC_BYTIND (buf, newmin); | |
885 newsize = bytmin - newmin; | |
886 if (newsize != size) | |
887 { | |
888 bufmax = bufmin; | |
889 bytmax = bytmin; | |
890 size = newsize; | |
891 } | |
892 bytmin = newmin; | |
893 bufmin--; | |
894 } | |
895 retval = bufmin; | |
896 | |
897 /* #### Should go past the found location to reduce the number | |
898 of times that this function is called | |
899 */ | |
900 } | |
901 | |
902 /* If size is three, than we have to max sure that the range we | |
903 discovered isn't too large, because we use a fixed-length | |
904 table to divide by 3. */ | |
905 | |
906 if (size == 3) | |
907 { | |
908 int gap = bytmax - bytmin; | |
909 buf->text->mule_three_p = 1; | |
910 buf->text->mule_shifter = 1; | |
911 | |
912 if (gap > MAX_BYTIND_GAP_SIZE_3) | |
913 { | |
914 if (forward_p) | |
915 { | |
916 bytmin = bytmax - MAX_BYTIND_GAP_SIZE_3; | |
917 bufmin = bufmax - MAX_BUFPOS_GAP_SIZE_3; | |
918 } | |
919 else | |
920 { | |
921 bytmax = bytmin + MAX_BYTIND_GAP_SIZE_3; | |
922 bufmax = bufmin + MAX_BUFPOS_GAP_SIZE_3; | |
923 } | |
924 } | |
925 } | |
926 else | |
927 { | |
928 buf->text->mule_three_p = 0; | |
929 if (size == 4) | |
930 buf->text->mule_shifter = 2; | |
931 else | |
932 buf->text->mule_shifter = size - 1; | |
933 } | |
934 | |
935 buf->text->mule_bufmin = bufmin; | |
936 buf->text->mule_bufmax = bufmax; | |
937 buf->text->mule_bytmin = bytmin; | |
938 buf->text->mule_bytmax = bytmax; | |
939 | |
940 if (add_to_cache) | |
941 { | |
942 int replace_loc; | |
943 | |
944 /* We throw away a "random" cached value and replace it with | |
945 the new value. It doesn't actually have to be very random | |
946 at all, just evenly distributed. | |
947 | |
948 #### It would be better to use a least-recently-used algorithm | |
949 or something that tries to space things out, but I'm not sure | |
950 it's worth it to go to the trouble of maintaining that. */ | |
951 not_very_random_number += 621; | |
952 replace_loc = not_very_random_number & 15; | |
953 buf->text->mule_bufpos_cache[replace_loc] = retval; | |
954 buf->text->mule_bytind_cache[replace_loc] = x; | |
955 } | |
956 | |
957 return retval; | |
958 } | |
959 | |
960 /* Text of length BYTELENGTH and CHARLENGTH (in different units) | |
961 was inserted at bufpos START. */ | |
962 | |
963 static void | |
964 buffer_mule_signal_inserted_region (struct buffer *buf, Bufpos start, | |
965 Bytecount bytelength, | |
966 Charcount charlength) | |
967 { | |
968 int size = (1 << buf->text->mule_shifter) + !!buf->text->mule_three_p; | |
969 int i; | |
970 | |
971 /* Adjust the cache of known positions. */ | |
972 for (i = 0; i < 16; i++) | |
973 { | |
974 | |
975 if (buf->text->mule_bufpos_cache[i] > start) | |
976 { | |
977 buf->text->mule_bufpos_cache[i] += charlength; | |
978 buf->text->mule_bytind_cache[i] += bytelength; | |
979 } | |
980 } | |
981 | |
982 if (start >= buf->text->mule_bufmax) | |
983 return; | |
984 | |
985 /* The insertion is either before the known region, in which case | |
986 it shoves it forward; or within the known region, in which case | |
987 it shoves the end forward. (But it may make the known region | |
988 inconsistent, so we may have to shorten it.) */ | |
989 | |
990 if (start <= buf->text->mule_bufmin) | |
991 { | |
992 buf->text->mule_bufmin += charlength; | |
993 buf->text->mule_bufmax += charlength; | |
994 buf->text->mule_bytmin += bytelength; | |
995 buf->text->mule_bytmax += bytelength; | |
996 } | |
997 else | |
998 { | |
999 Bufpos end = start + charlength; | |
1000 /* the insertion point divides the known region in two. | |
1001 Keep the longer half, at least, and expand into the | |
1002 inserted chunk as much as possible. */ | |
1003 | |
1004 if (start - buf->text->mule_bufmin > buf->text->mule_bufmax - start) | |
1005 { | |
1006 Bytind bytestart = (buf->text->mule_bytmin | |
1007 + size * (start - buf->text->mule_bufmin)); | |
1008 Bytind bytenew; | |
1009 | |
1010 while (start < end) | |
1011 { | |
1012 bytenew = bytestart; | |
1013 INC_BYTIND (buf, bytenew); | |
1014 if (bytenew - bytestart != size) | |
1015 break; | |
1016 start++; | |
1017 bytestart = bytenew; | |
1018 } | |
1019 if (start != end) | |
1020 { | |
1021 buf->text->mule_bufmax = start; | |
1022 buf->text->mule_bytmax = bytestart; | |
1023 } | |
1024 else | |
1025 { | |
1026 buf->text->mule_bufmax += charlength; | |
1027 buf->text->mule_bytmax += bytelength; | |
1028 } | |
1029 } | |
1030 else | |
1031 { | |
1032 Bytind byteend = (buf->text->mule_bytmin | |
1033 + size * (start - buf->text->mule_bufmin) | |
1034 + bytelength); | |
1035 Bytind bytenew; | |
1036 | |
1037 buf->text->mule_bufmax += charlength; | |
1038 buf->text->mule_bytmax += bytelength; | |
1039 | |
1040 while (end > start) | |
1041 { | |
1042 bytenew = byteend; | |
1043 DEC_BYTIND (buf, bytenew); | |
1044 if (byteend - bytenew != size) | |
1045 break; | |
1046 end--; | |
1047 byteend = bytenew; | |
1048 } | |
1049 if (start != end) | |
1050 { | |
1051 buf->text->mule_bufmin = end; | |
1052 buf->text->mule_bytmin = byteend; | |
1053 } | |
1054 } | |
1055 } | |
1056 } | |
1057 | |
1058 /* Text from START to END (equivalent in Bytinds: from BI_START to | |
1059 BI_END) was deleted. */ | |
1060 | |
1061 static void | |
1062 buffer_mule_signal_deleted_region (struct buffer *buf, Bufpos start, | |
1063 Bufpos end, Bytind bi_start, | |
1064 Bytind bi_end) | |
1065 { | |
1066 int i; | |
1067 | |
1068 /* Adjust the cache of known positions. */ | |
1069 for (i = 0; i < 16; i++) | |
1070 { | |
1071 /* After the end; gets shoved backward */ | |
1072 if (buf->text->mule_bufpos_cache[i] > end) | |
1073 { | |
1074 buf->text->mule_bufpos_cache[i] -= end - start; | |
1075 buf->text->mule_bytind_cache[i] -= bi_end - bi_start; | |
1076 } | |
1077 /* In the range; moves to start of range */ | |
1078 else if (buf->text->mule_bufpos_cache[i] > start) | |
1079 { | |
1080 buf->text->mule_bufpos_cache[i] = start; | |
1081 buf->text->mule_bytind_cache[i] = bi_start; | |
1082 } | |
1083 } | |
1084 | |
1085 /* We don't care about any text after the end of the known region. */ | |
1086 | |
1087 end = min (end, buf->text->mule_bufmax); | |
1088 bi_end = min (bi_end, buf->text->mule_bytmax); | |
1089 if (start >= end) | |
1090 return; | |
1091 | |
1092 /* The end of the known region offsets by the total amount of deletion, | |
1093 since it's all before it. */ | |
1094 | |
1095 buf->text->mule_bufmax -= end - start; | |
1096 buf->text->mule_bytmax -= bi_end - bi_start; | |
1097 | |
1098 /* Now we don't care about any text after the start of the known region. */ | |
1099 | |
1100 end = min (end, buf->text->mule_bufmin); | |
1101 bi_end = min (bi_end, buf->text->mule_bytmin); | |
1102 if (start >= end) | |
1103 return; | |
1104 | |
1105 buf->text->mule_bufmin -= end - start; | |
1106 buf->text->mule_bytmin -= bi_end - bi_start; | |
1107 } | |
1108 | |
1109 #endif /* MULE */ | |
1110 | |
1111 #ifdef ERROR_CHECK_BUFPOS | |
1112 | |
1113 Bytind | |
1114 bufpos_to_bytind (struct buffer *buf, Bufpos x) | |
1115 { | |
1116 Bytind retval = real_bufpos_to_bytind (buf, x); | |
1117 ASSERT_VALID_BYTIND_UNSAFE (buf, retval); | |
1118 return retval; | |
1119 } | |
1120 | |
1121 Bufpos | |
1122 bytind_to_bufpos (struct buffer *buf, Bytind x) | |
1123 { | |
1124 ASSERT_VALID_BYTIND_UNSAFE (buf, x); | |
1125 return real_bytind_to_bufpos (buf, x); | |
1126 } | |
1127 | |
1128 #endif /* ERROR_CHECK_BUFPOS */ | |
1129 | |
1130 | |
1131 /************************************************************************/ | |
1132 /* verifying buffer and string positions */ | |
1133 /************************************************************************/ | |
1134 | |
1135 /* Functions below are tagged with either _byte or _char indicating | |
1136 whether they return byte or character positions. For a buffer, | |
1137 a character position is a "Bufpos" and a byte position is a "Bytind". | |
1138 For strings, these are sometimes typed using "Charcount" and | |
1139 "Bytecount". */ | |
1140 | |
1141 /* Flags for the functions below are: | |
1142 | |
1143 GB_ALLOW_PAST_ACCESSIBLE | |
1144 | |
1145 Allow positions to range over the entire buffer (BUF_BEG to BUF_Z), | |
1146 rather than just the accessible portion (BUF_BEGV to BUF_ZV). | |
1147 For strings, this flag has no effect. | |
1148 | |
1149 GB_COERCE_RANGE | |
1150 | |
1151 If the position is outside the allowable range, return the lower | |
1152 or upper bound of the range, whichever is closer to the specified | |
1153 position. | |
1154 | |
1155 GB_NO_ERROR_IF_BAD | |
1156 | |
1157 If the position is outside the allowable range, return -1. | |
1158 | |
1159 GB_NEGATIVE_FROM_END | |
1160 | |
1161 If a value is negative, treat it as an offset from the end. | |
1162 Only applies to strings. | |
1163 | |
1164 The following additional flags apply only to the functions | |
1165 that return ranges: | |
1166 | |
1167 GB_ALLOW_NIL | |
1168 | |
1169 Either or both positions can be nil. If FROM is nil, | |
1170 FROM_OUT will contain the lower bound of the allowed range. | |
1171 If TO is nil, TO_OUT will contain the upper bound of the | |
1172 allowed range. | |
1173 | |
1174 GB_CHECK_ORDER | |
1175 | |
1176 FROM must contain the lower bound and TO the upper bound | |
1177 of the range. If the positions are reversed, an error is | |
1178 signalled. | |
1179 | |
1180 The following is a combination flag: | |
1181 | |
1182 GB_HISTORICAL_STRING_BEHAVIOR | |
1183 | |
1184 Equivalent to (GB_NEGATIVE_FROM_END | GB_ALLOW_NIL). | |
1185 */ | |
1186 | |
1187 /* Return a buffer position stored in a Lisp_Object. Full | |
1188 error-checking is done on the position. Flags can be specified to | |
1189 control the behavior of out-of-range values. The default behavior | |
1190 is to require that the position is within the accessible part of | |
1191 the buffer (BEGV and ZV), and to signal an error if the position is | |
1192 out of range. | |
1193 | |
1194 */ | |
1195 | |
1196 Bufpos | |
1197 get_buffer_pos_char (struct buffer *b, Lisp_Object pos, unsigned int flags) | |
1198 { | |
1199 Bufpos ind; | |
1200 Bufpos min_allowed, max_allowed; | |
1201 | |
1202 CHECK_INT_COERCE_MARKER (pos); | |
1203 ind = XINT (pos); | |
1204 min_allowed = flags & GB_ALLOW_PAST_ACCESSIBLE ? BUF_BEG (b) : BUF_BEGV (b); | |
1205 max_allowed = flags & GB_ALLOW_PAST_ACCESSIBLE ? BUF_Z (b) : BUF_ZV (b); | |
1206 | |
1207 if (ind < min_allowed || ind > max_allowed) | |
1208 { | |
1209 if (flags & GB_COERCE_RANGE) | |
1210 ind = ind < min_allowed ? min_allowed : max_allowed; | |
1211 else if (flags & GB_NO_ERROR_IF_BAD) | |
1212 ind = -1; | |
1213 else | |
1214 { | |
1215 Lisp_Object buffer; | |
1216 XSETBUFFER (buffer, b); | |
1217 args_out_of_range (buffer, pos); | |
1218 } | |
1219 } | |
1220 | |
1221 return ind; | |
1222 } | |
1223 | |
1224 Bytind | |
1225 get_buffer_pos_byte (struct buffer *b, Lisp_Object pos, unsigned int flags) | |
1226 { | |
1227 Bufpos bpos = get_buffer_pos_char (b, pos, flags); | |
1228 if (bpos < 0) /* could happen with GB_NO_ERROR_IF_BAD */ | |
1229 return -1; | |
1230 return bufpos_to_bytind (b, bpos); | |
1231 } | |
1232 | |
1233 /* Return a pair of buffer positions representing a range of text, | |
1234 taken from a pair of Lisp_Objects. Full error-checking is | |
1235 done on the positions. Flags can be specified to control the | |
1236 behavior of out-of-range values. The default behavior is to | |
1237 allow the range bounds to be specified in either order | |
1238 (however, FROM_OUT will always be the lower bound of the range | |
1239 and TO_OUT the upper bound),to require that the positions | |
1240 are within the accessible part of the buffer (BEGV and ZV), | |
1241 and to signal an error if the positions are out of range. | |
1242 */ | |
1243 | |
1244 void | |
1245 get_buffer_range_char (struct buffer *b, Lisp_Object from, Lisp_Object to, | |
1246 Bufpos *from_out, Bufpos *to_out, unsigned int flags) | |
1247 { | |
1248 Bufpos min_allowed, max_allowed; | |
1249 | |
1250 min_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ? | |
1251 BUF_BEG (b) : BUF_BEGV (b); | |
1252 max_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ? | |
1253 BUF_Z (b) : BUF_ZV (b); | |
1254 | |
1255 if (NILP (from) && (flags & GB_ALLOW_NIL)) | |
1256 *from_out = min_allowed; | |
1257 else | |
1258 *from_out = get_buffer_pos_char (b, from, flags | GB_NO_ERROR_IF_BAD); | |
1259 | |
1260 if (NILP (to) && (flags & GB_ALLOW_NIL)) | |
1261 *to_out = max_allowed; | |
1262 else | |
1263 *to_out = get_buffer_pos_char (b, to, flags | GB_NO_ERROR_IF_BAD); | |
1264 | |
1265 if ((*from_out < 0 || *to_out < 0) && !(flags & GB_NO_ERROR_IF_BAD)) | |
1266 { | |
1267 Lisp_Object buffer; | |
1268 XSETBUFFER (buffer, b); | |
1269 args_out_of_range_3 (buffer, from, to); | |
1270 } | |
1271 | |
1272 if (*from_out >= 0 && *to_out >= 0 && *from_out > *to_out) | |
1273 { | |
1274 if (flags & GB_CHECK_ORDER) | |
1275 signal_simple_error_2 ("start greater than end", from, to); | |
1276 else | |
1277 { | |
1278 Bufpos temp = *from_out; | |
1279 *from_out = *to_out; | |
1280 *to_out = temp; | |
1281 } | |
1282 } | |
1283 } | |
1284 | |
1285 void | |
1286 get_buffer_range_byte (struct buffer *b, Lisp_Object from, Lisp_Object to, | |
1287 Bytind *from_out, Bytind *to_out, unsigned int flags) | |
1288 { | |
1289 Bufpos s, e; | |
1290 | |
1291 get_buffer_range_char (b, from, to, &s, &e, flags); | |
1292 if (s >= 0) | |
1293 *from_out = bufpos_to_bytind (b, s); | |
1294 else /* could happen with GB_NO_ERROR_IF_BAD */ | |
1295 *from_out = -1; | |
1296 if (e >= 0) | |
1297 *to_out = bufpos_to_bytind (b, e); | |
1298 else | |
1299 *to_out = -1; | |
1300 } | |
1301 | |
1302 static Charcount | |
1303 get_string_pos_char_1 (Lisp_Object string, Lisp_Object pos, unsigned int flags, | |
1304 Charcount known_length) | |
1305 { | |
1306 Charcount ccpos; | |
1307 Charcount min_allowed = 0; | |
1308 Charcount max_allowed = known_length; | |
1309 | |
1310 /* Computation of KNOWN_LENGTH is potentially expensive so we pass | |
1311 it in. */ | |
1312 CHECK_INT (pos); | |
1313 ccpos = XINT (pos); | |
1314 if (ccpos < 0 && flags & GB_NEGATIVE_FROM_END) | |
1315 ccpos += max_allowed; | |
1316 | |
1317 if (ccpos < min_allowed || ccpos > max_allowed) | |
1318 { | |
1319 if (flags & GB_COERCE_RANGE) | |
1320 ccpos = ccpos < min_allowed ? min_allowed : max_allowed; | |
1321 else if (flags & GB_NO_ERROR_IF_BAD) | |
1322 ccpos = -1; | |
1323 else | |
1324 args_out_of_range (string, pos); | |
1325 } | |
1326 | |
1327 return ccpos; | |
1328 } | |
1329 | |
1330 Charcount | |
1331 get_string_pos_char (Lisp_Object string, Lisp_Object pos, unsigned int flags) | |
1332 { | |
1333 return get_string_pos_char_1 (string, pos, flags, | |
1334 XSTRING_CHAR_LENGTH (string)); | |
1335 } | |
1336 | |
1337 Bytecount | |
1338 get_string_pos_byte (Lisp_Object string, Lisp_Object pos, unsigned int flags) | |
1339 { | |
1340 Charcount ccpos = get_string_pos_char (string, pos, flags); | |
1341 if (ccpos < 0) /* could happen with GB_NO_ERROR_IF_BAD */ | |
1342 return -1; | |
1343 return charcount_to_bytecount (XSTRING_DATA (string), ccpos); | |
1344 } | |
1345 | |
1346 void | |
1347 get_string_range_char (Lisp_Object string, Lisp_Object from, Lisp_Object to, | |
1348 Charcount *from_out, Charcount *to_out, | |
1349 unsigned int flags) | |
1350 { | |
1351 Charcount min_allowed = 0; | |
1352 Charcount max_allowed = XSTRING_CHAR_LENGTH (string); | |
1353 | |
1354 if (NILP (from) && (flags & GB_ALLOW_NIL)) | |
1355 *from_out = min_allowed; | |
1356 else | |
1357 *from_out = get_string_pos_char_1 (string, from, | |
1358 flags | GB_NO_ERROR_IF_BAD, | |
1359 max_allowed); | |
1360 | |
1361 if (NILP (to) && (flags & GB_ALLOW_NIL)) | |
1362 *to_out = max_allowed; | |
1363 else | |
1364 *to_out = get_string_pos_char_1 (string, to, | |
1365 flags | GB_NO_ERROR_IF_BAD, | |
1366 max_allowed); | |
1367 | |
1368 if ((*from_out < 0 || *to_out < 0) && !(flags & GB_NO_ERROR_IF_BAD)) | |
1369 args_out_of_range_3 (string, from, to); | |
1370 | |
1371 if (*from_out >= 0 && *to_out >= 0 && *from_out > *to_out) | |
1372 { | |
1373 if (flags & GB_CHECK_ORDER) | |
1374 signal_simple_error_2 ("start greater than end", from, to); | |
1375 else | |
1376 { | |
1377 Bufpos temp = *from_out; | |
1378 *from_out = *to_out; | |
1379 *to_out = temp; | |
1380 } | |
1381 } | |
1382 } | |
1383 | |
1384 void | |
1385 get_string_range_byte (Lisp_Object string, Lisp_Object from, Lisp_Object to, | |
1386 Bytecount *from_out, Bytecount *to_out, | |
1387 unsigned int flags) | |
1388 { | |
1389 Charcount s, e; | |
1390 | |
1391 get_string_range_char (string, from, to, &s, &e, flags); | |
1392 if (s >= 0) | |
1393 *from_out = charcount_to_bytecount (XSTRING_DATA (string), s); | |
1394 else /* could happen with GB_NO_ERROR_IF_BAD */ | |
1395 *from_out = -1; | |
1396 if (e >= 0) | |
1397 *to_out = charcount_to_bytecount (XSTRING_DATA (string), e); | |
1398 else | |
1399 *to_out = -1; | |
1400 | |
1401 } | |
1402 | |
1403 Bufpos | |
1404 get_buffer_or_string_pos_char (Lisp_Object object, Lisp_Object pos, | |
1405 unsigned int flags) | |
1406 { | |
1407 return STRINGP (object) ? | |
1408 get_string_pos_char (object, pos, flags) : | |
1409 get_buffer_pos_char (XBUFFER (object), pos, flags); | |
1410 } | |
1411 | |
1412 Bytind | |
1413 get_buffer_or_string_pos_byte (Lisp_Object object, Lisp_Object pos, | |
1414 unsigned int flags) | |
1415 { | |
1416 return STRINGP (object) ? | |
1417 get_string_pos_byte (object, pos, flags) : | |
1418 get_buffer_pos_byte (XBUFFER (object), pos, flags); | |
1419 } | |
1420 | |
1421 void | |
1422 get_buffer_or_string_range_char (Lisp_Object object, Lisp_Object from, | |
1423 Lisp_Object to, Bufpos *from_out, | |
1424 Bufpos *to_out, unsigned int flags) | |
1425 { | |
1426 if (STRINGP (object)) | |
1427 get_string_range_char (object, from, to, from_out, to_out, flags); | |
1428 else | |
1429 get_buffer_range_char (XBUFFER (object), from, to, from_out, to_out, flags); | |
1430 } | |
1431 | |
1432 void | |
1433 get_buffer_or_string_range_byte (Lisp_Object object, Lisp_Object from, | |
1434 Lisp_Object to, Bytind *from_out, | |
1435 Bytind *to_out, unsigned int flags) | |
1436 { | |
1437 if (STRINGP (object)) | |
1438 get_string_range_byte (object, from, to, from_out, to_out, flags); | |
1439 else | |
1440 get_buffer_range_byte (XBUFFER (object), from, to, from_out, to_out, flags); | |
1441 } | |
1442 | |
1443 Bufpos | |
1444 buffer_or_string_accessible_begin_char (Lisp_Object object) | |
1445 { | |
1446 return STRINGP (object) ? 0 : BUF_BEGV (XBUFFER (object)); | |
1447 } | |
1448 | |
1449 Bufpos | |
1450 buffer_or_string_accessible_end_char (Lisp_Object object) | |
1451 { | |
1452 return STRINGP (object) ? | |
1453 XSTRING_CHAR_LENGTH (object) : BUF_ZV (XBUFFER (object)); | |
1454 } | |
1455 | |
1456 Bytind | |
1457 buffer_or_string_accessible_begin_byte (Lisp_Object object) | |
1458 { | |
1459 return STRINGP (object) ? 0 : BI_BUF_BEGV (XBUFFER (object)); | |
1460 } | |
1461 | |
1462 Bytind | |
1463 buffer_or_string_accessible_end_byte (Lisp_Object object) | |
1464 { | |
1465 return STRINGP (object) ? | |
1466 XSTRING_LENGTH (object) : BI_BUF_ZV (XBUFFER (object)); | |
1467 } | |
1468 | |
1469 Bufpos | |
1470 buffer_or_string_absolute_begin_char (Lisp_Object object) | |
1471 { | |
1472 return STRINGP (object) ? 0 : BUF_BEG (XBUFFER (object)); | |
1473 } | |
1474 | |
1475 Bufpos | |
1476 buffer_or_string_absolute_end_char (Lisp_Object object) | |
1477 { | |
1478 return STRINGP (object) ? | |
1479 XSTRING_CHAR_LENGTH (object) : BUF_Z (XBUFFER (object)); | |
1480 } | |
1481 | |
1482 Bytind | |
1483 buffer_or_string_absolute_begin_byte (Lisp_Object object) | |
1484 { | |
1485 return STRINGP (object) ? 0 : BI_BUF_BEG (XBUFFER (object)); | |
1486 } | |
1487 | |
1488 Bytind | |
1489 buffer_or_string_absolute_end_byte (Lisp_Object object) | |
1490 { | |
1491 return STRINGP (object) ? | |
1492 XSTRING_LENGTH (object) : BI_BUF_Z (XBUFFER (object)); | |
1493 } | |
1494 | |
1495 | |
1496 /************************************************************************/ | |
1497 /* point and marker adjustment */ | |
1498 /************************************************************************/ | |
1499 | |
1500 /* just_set_point() is the only place `PT' is an lvalue in all of emacs. | |
1501 This function is called from set_buffer_point(), which is the function | |
1502 that the SET_PT and BUF_SET_PT macros expand into, and from the | |
1503 routines below that insert and delete text. (This is in cases where | |
1504 the point marker logically doesn't move but PT (being a byte index) | |
1505 needs to get adjusted.) */ | |
1506 | |
1507 /* Set point to a specified value. This is used only when the value | |
1508 of point changes due to an insert or delete; it does not represent | |
1509 a conceptual change in point as a marker. In particular, point is | |
1510 not crossing any interval boundaries, so there's no need to use the | |
1511 usual SET_PT macro. In fact it would be incorrect to do so, because | |
1512 either the old or the new value of point is out of synch with the | |
1513 current set of intervals. */ | |
1514 | |
1515 /* This gets called more than enough to make the function call | |
1516 overhead a significant factor so we've turned it into a macro. */ | |
1517 #define JUST_SET_POINT(buf, bufpos, ind) \ | |
1518 do \ | |
1519 { \ | |
1520 buf->bufpt = (bufpos); \ | |
1521 buf->pt = (ind); \ | |
1522 } while (0) | |
1523 | |
1524 /* Set a buffer's point. */ | |
1525 | |
1526 void | |
1527 set_buffer_point (struct buffer *buf, Bufpos bufpos, Bytind bytpos) | |
1528 { | |
1529 assert (bytpos >= BI_BUF_BEGV (buf) && bytpos <= BI_BUF_ZV (buf)); | |
1530 if (bytpos == BI_BUF_PT (buf)) | |
1531 return; | |
1532 JUST_SET_POINT (buf, bufpos, bytpos); | |
1533 MARK_POINT_CHANGED; | |
1534 assert (MARKERP (buf->point_marker)); | |
1535 XMARKER (buf->point_marker)->memind = | |
1536 bytind_to_memind (buf, bytpos); | |
1537 | |
1538 /* FSF makes sure that PT is not being set within invisible text. | |
1539 However, this is the wrong place for that check. The check | |
1540 should happen only at the next redisplay. */ | |
1541 | |
1542 /* Some old coder said: | |
1543 | |
1544 "If there were to be hooks which were run when point entered/left an | |
1545 extent, this would be the place to put them. | |
1546 | |
1547 However, it's probably the case that such hooks should be implemented | |
1548 using a post-command-hook instead, to avoid running the hooks as a | |
1549 result of intermediate motion inside of save-excursions, for example." | |
1550 | |
1551 I definitely agree with this. PT gets moved all over the place | |
1552 and it would be a Bad Thing for any hooks to get called, both for | |
1553 the reason above and because many callers are not prepared for | |
1554 a GC within this function. --ben | |
1555 */ | |
1556 } | |
1557 | |
1558 /* Do the correct marker-like adjustment on MPOS (see below). FROM, TO, | |
1559 and AMOUNT are as in adjust_markers(). If MPOS doesn't need to be | |
1560 adjusted, nothing will happen. */ | |
1561 Memind | |
1562 do_marker_adjustment (Memind mpos, Memind from, | |
1563 Memind to, Bytecount amount) | |
1564 { | |
1565 if (amount > 0) | |
1566 { | |
1567 if (mpos > to && mpos < to + amount) | |
1568 mpos = to + amount; | |
1569 } | |
1570 else | |
1571 { | |
1572 if (mpos > from + amount && mpos <= from) | |
1573 mpos = from + amount; | |
1574 } | |
1575 if (mpos > from && mpos <= to) | |
1576 mpos += amount; | |
1577 return mpos; | |
1578 } | |
1579 | |
1580 /* Do the following: | |
1581 | |
1582 (1) Add `amount' to the position of every marker in the current buffer | |
1583 whose current position is between `from' (exclusive) and `to' (inclusive). | |
1584 | |
1585 (2) Also, any markers past the outside of that interval, in the direction | |
1586 of adjustment, are first moved back to the near end of the interval | |
1587 and then adjusted by `amount'. | |
1588 | |
1589 This function is called in two different cases: when a region of | |
1590 characters adjacent to the gap is moved, causing the gap to shift | |
1591 to the other side of the region (in this case, `from' and `to' | |
1592 point to the old position of the region and there should be no | |
1593 markers affected by (2) because they would be inside the gap), | |
1594 or when a region of characters adjacent to the gap is wiped out, | |
1595 causing the gap to increase to include the region (in this case, | |
1596 `from' and `to' are the same, both pointing to the boundary | |
1597 between the gap and the deleted region, and there are no markers | |
1598 affected by (1)). | |
1599 | |
1600 The reason for the use of exclusive and inclusive is that markers at | |
1601 the gap always sit at the beginning, not at the end. | |
1602 */ | |
1603 | |
1604 static void | |
1605 adjust_markers (struct buffer *buf, Memind from, Memind to, | |
1606 Bytecount amount) | |
1607 { | |
1608 struct Lisp_Marker *m; | |
1609 | |
1610 for (m = BUF_MARKERS (buf); m; m = marker_next (m)) | |
1611 m->memind = do_marker_adjustment (m->memind, from, to, amount); | |
1612 } | |
1613 | |
1614 /* Adjust markers whose insertion-type is t | |
1615 for an insertion of AMOUNT characters at POS. */ | |
1616 | |
1617 static void | |
1618 adjust_markers_for_insert (struct buffer *buf, Memind ind, Bytecount amount) | |
1619 { | |
1620 struct Lisp_Marker *m; | |
1621 | |
1622 for (m = BUF_MARKERS (buf); m; m = marker_next (m)) | |
1623 { | |
1624 if (m->insertion_type && m->memind == ind) | |
1625 m->memind += amount; | |
1626 } | |
1627 } | |
1628 | |
1629 | |
1630 /************************************************************************/ | |
1631 /* Routines for dealing with the gap */ | |
1632 /************************************************************************/ | |
1633 | |
1634 /* XEmacs requires an ANSI C compiler, and it damn well better have a | |
1635 working memmove() */ | |
1636 #define GAP_USE_BCOPY | |
1637 #ifdef BCOPY_UPWARD_SAFE | |
1638 # undef BCOPY_UPWARD_SAFE | |
1639 #endif | |
1640 #ifdef BCOPY_DOWNWARD_SAFE | |
1641 # undef BCOPY_DOWNWARD_SAFE | |
1642 #endif | |
1643 #define BCOPY_UPWARD_SAFE 1 | |
1644 #define BCOPY_DOWNWARD_SAFE 1 | |
1645 | |
1646 /* maximum amount of memory moved in a single chunk. Increasing this | |
1647 value improves gap-motion efficiency but decreases QUIT responsiveness | |
1648 time. Was 32000 but today's processors are faster and files are | |
1649 bigger. --ben */ | |
1650 #define GAP_MOVE_CHUNK 300000 | |
1651 | |
1652 /* Move the gap to POS, which is less than the current GPT. */ | |
1653 | |
1654 static void | |
1655 gap_left (struct buffer *buf, Bytind pos) | |
1656 { | |
1657 Bufbyte *to, *from; | |
1658 Bytecount i; | |
1659 Bytind new_s1; | |
1660 struct buffer *mbuf; | |
1661 Lisp_Object bufcons; | |
1662 | |
1663 from = BUF_GPT_ADDR (buf); | |
1664 to = from + BUF_GAP_SIZE (buf); | |
1665 new_s1 = BI_BUF_GPT (buf); | |
1666 | |
1667 /* Now copy the characters. To move the gap down, | |
1668 copy characters up. */ | |
1669 | |
1670 while (1) | |
1671 { | |
1672 /* I gets number of characters left to copy. */ | |
1673 i = new_s1 - pos; | |
1674 if (i == 0) | |
1675 break; | |
1676 /* If a quit is requested, stop copying now. | |
1677 Change POS to be where we have actually moved the gap to. */ | |
1678 if (QUITP) | |
1679 { | |
1680 pos = new_s1; | |
1681 break; | |
1682 } | |
1683 /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */ | |
1684 if (i > GAP_MOVE_CHUNK) | |
1685 i = GAP_MOVE_CHUNK; | |
1686 #ifdef GAP_USE_BCOPY | |
1687 if (i >= 128 | |
1688 /* bcopy is safe if the two areas of memory do not overlap | |
1689 or on systems where bcopy is always safe for moving upward. */ | |
1690 && (BCOPY_UPWARD_SAFE | |
1691 || to - from >= 128)) | |
1692 { | |
1693 /* If overlap is not safe, avoid it by not moving too many | |
1694 characters at once. */ | |
1695 if (!BCOPY_UPWARD_SAFE && i > to - from) | |
1696 i = to - from; | |
1697 new_s1 -= i; | |
1698 from -= i, to -= i; | |
1699 memmove (to, from, i); | |
1700 } | |
1701 else | |
1702 #endif | |
1703 { | |
1704 new_s1 -= i; | |
1705 while (--i >= 0) | |
1706 *--to = *--from; | |
1707 } | |
1708 } | |
1709 | |
1710 /* Adjust markers, and buffer data structure, to put the gap at POS. | |
1711 POS is where the loop above stopped, which may be what was specified | |
1712 or may be where a quit was detected. */ | |
1713 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
1714 { | |
1715 adjust_markers (mbuf, pos, BI_BUF_GPT (mbuf), BUF_GAP_SIZE (mbuf)); | |
1716 } | |
1717 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
1718 { | |
1719 adjust_extents (make_buffer (mbuf), pos, BI_BUF_GPT (mbuf), | |
1720 BUF_GAP_SIZE (mbuf)); | |
1721 } | |
1722 SET_BI_BUF_GPT (buf, pos); | |
1723 SET_GAP_SENTINEL (buf); | |
1724 #ifdef ERROR_CHECK_EXTENTS | |
1725 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
1726 { | |
1727 sledgehammer_extent_check (make_buffer (mbuf)); | |
1728 } | |
1729 #endif | |
1730 QUIT; | |
1731 } | |
1732 | |
1733 static void | |
1734 gap_right (struct buffer *buf, Bytind pos) | |
1735 { | |
1736 Bufbyte *to, *from; | |
1737 Bytecount i; | |
1738 Bytind new_s1; | |
1739 struct buffer *mbuf; | |
1740 Lisp_Object bufcons; | |
1741 | |
1742 to = BUF_GPT_ADDR (buf); | |
1743 from = to + BUF_GAP_SIZE (buf); | |
1744 new_s1 = BI_BUF_GPT (buf); | |
1745 | |
1746 /* Now copy the characters. To move the gap up, | |
1747 copy characters down. */ | |
1748 | |
1749 while (1) | |
1750 { | |
1751 /* I gets number of characters left to copy. */ | |
1752 i = pos - new_s1; | |
1753 if (i == 0) | |
1754 break; | |
1755 /* If a quit is requested, stop copying now. | |
1756 Change POS to be where we have actually moved the gap to. */ | |
1757 if (QUITP) | |
1758 { | |
1759 pos = new_s1; | |
1760 break; | |
1761 } | |
1762 /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */ | |
1763 if (i > GAP_MOVE_CHUNK) | |
1764 i = GAP_MOVE_CHUNK; | |
1765 #ifdef GAP_USE_BCOPY | |
1766 if (i >= 128 | |
1767 /* bcopy is safe if the two areas of memory do not overlap | |
1768 or on systems where bcopy is always safe for moving downward. */ | |
1769 && (BCOPY_DOWNWARD_SAFE | |
1770 || from - to >= 128)) | |
1771 { | |
1772 /* If overlap is not safe, avoid it by not moving too many | |
1773 characters at once. */ | |
1774 if (!BCOPY_DOWNWARD_SAFE && i > from - to) | |
1775 i = from - to; | |
1776 new_s1 += i; | |
1777 memmove (to, from, i); | |
1778 from += i, to += i; | |
1779 } | |
1780 else | |
1781 #endif | |
1782 { | |
1783 new_s1 += i; | |
1784 while (--i >= 0) | |
1785 *to++ = *from++; | |
1786 } | |
1787 } | |
1788 | |
1789 { | |
1790 int gsize = BUF_GAP_SIZE (buf); | |
1791 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
1792 { | |
1793 adjust_markers (mbuf, BI_BUF_GPT (mbuf) + gsize, pos + gsize, - gsize); | |
1794 } | |
1795 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
1796 { | |
1797 adjust_extents (make_buffer (mbuf), BI_BUF_GPT (mbuf) + gsize, | |
1798 pos + gsize, - gsize); | |
1799 } | |
1800 SET_BI_BUF_GPT (buf, pos); | |
1801 SET_GAP_SENTINEL (buf); | |
1802 #ifdef ERROR_CHECK_EXTENTS | |
1803 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
1804 { | |
1805 sledgehammer_extent_check (make_buffer (mbuf)); | |
1806 } | |
1807 #endif | |
1808 } | |
1809 if (pos == BI_BUF_Z (buf)) | |
1810 { | |
1811 /* merge gap with end gap */ | |
1812 | |
1813 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + BUF_END_GAP_SIZE (buf)); | |
1814 SET_BUF_END_GAP_SIZE (buf, 0); | |
1815 SET_END_SENTINEL (buf); | |
1816 } | |
1817 | |
1818 QUIT; | |
1819 } | |
1820 | |
1821 /* Move gap to position `pos'. | |
1822 Note that this can quit! */ | |
1823 | |
1824 static void | |
1825 move_gap (struct buffer *buf, Bytind pos) | |
1826 { | |
1827 if (! BUF_BEG_ADDR (buf)) | |
1828 abort (); | |
1829 if (pos < BI_BUF_GPT (buf)) | |
1830 gap_left (buf, pos); | |
1831 else if (pos > BI_BUF_GPT (buf)) | |
1832 gap_right (buf, pos); | |
1833 } | |
1834 | |
1835 /* Merge the end gap into the gap */ | |
1836 | |
1837 static void | |
1838 merge_gap_with_end_gap (struct buffer *buf) | |
1839 { | |
1840 Lisp_Object tem; | |
1841 Bytind real_gap_loc; | |
1842 Bytecount old_gap_size; | |
1843 Bytecount increment; | |
1844 | |
1845 increment = BUF_END_GAP_SIZE (buf); | |
1846 SET_BUF_END_GAP_SIZE (buf, 0); | |
1847 | |
1848 if (increment > 0) | |
1849 { | |
1850 /* Prevent quitting in move_gap. */ | |
1851 tem = Vinhibit_quit; | |
1852 Vinhibit_quit = Qt; | |
1853 | |
1854 real_gap_loc = BI_BUF_GPT (buf); | |
1855 old_gap_size = BUF_GAP_SIZE (buf); | |
1856 | |
1857 /* Pretend the end gap is the gap */ | |
1858 SET_BI_BUF_GPT (buf, BI_BUF_Z (buf) + BUF_GAP_SIZE (buf)); | |
1859 SET_BUF_GAP_SIZE (buf, increment); | |
1860 | |
1861 /* Move the new gap down to be consecutive with the end of the old one. | |
1862 This adjusts the markers properly too. */ | |
1863 gap_left (buf, real_gap_loc + old_gap_size); | |
1864 | |
1865 /* Now combine the two into one large gap. */ | |
1866 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + old_gap_size); | |
1867 SET_BI_BUF_GPT (buf, real_gap_loc); | |
1868 SET_GAP_SENTINEL (buf); | |
1869 | |
1870 /* We changed the total size of the buffer (including gap), | |
1871 so we need to fix up the end sentinel. */ | |
1872 SET_END_SENTINEL (buf); | |
1873 | |
1874 Vinhibit_quit = tem; | |
1875 } | |
1876 } | |
1877 | |
1878 /* Make the gap INCREMENT bytes longer. */ | |
1879 | |
1880 static void | |
1881 make_gap (struct buffer *buf, Bytecount increment) | |
1882 { | |
1883 Bufbyte *result; | |
1884 Lisp_Object tem; | |
1885 Bytind real_gap_loc; | |
1886 Bytecount old_gap_size; | |
1887 | |
1888 /* If we have to get more space, get enough to last a while. We use | |
1889 a geometric progression that saves on realloc space. */ | |
1890 increment += 2000 + ((BI_BUF_Z (buf) - BI_BUF_BEG (buf)) / 8); | |
1891 | |
1892 if (increment > BUF_END_GAP_SIZE (buf)) | |
1893 { | |
1894 /* Don't allow a buffer size that won't fit in an int | |
1895 even if it will fit in a Lisp integer. | |
1896 That won't work because so many places use `int'. */ | |
1897 | |
1898 if (BUF_Z (buf) - BUF_BEG (buf) + BUF_GAP_SIZE (buf) + increment | |
1899 > EMACS_INT_MAX) | |
1900 error ("Maximum buffer size exceeded"); | |
1901 | |
1902 result = BUFFER_REALLOC (buf->text->beg, | |
1903 BI_BUF_Z (buf) - BI_BUF_BEG (buf) + | |
1904 BUF_GAP_SIZE (buf) + increment + | |
1905 BUF_END_SENTINEL_SIZE); | |
1906 if (result == 0) | |
1907 memory_full (); | |
1908 | |
1909 SET_BUF_BEG_ADDR (buf, result); | |
1910 } | |
1911 else | |
1912 increment = BUF_END_GAP_SIZE (buf); | |
1913 | |
1914 /* Prevent quitting in move_gap. */ | |
1915 tem = Vinhibit_quit; | |
1916 Vinhibit_quit = Qt; | |
1917 | |
1918 real_gap_loc = BI_BUF_GPT (buf); | |
1919 old_gap_size = BUF_GAP_SIZE (buf); | |
1920 | |
1921 /* Call the newly allocated space a gap at the end of the whole space. */ | |
1922 SET_BI_BUF_GPT (buf, BI_BUF_Z (buf) + BUF_GAP_SIZE (buf)); | |
1923 SET_BUF_GAP_SIZE (buf, increment); | |
1924 | |
1925 SET_BUF_END_GAP_SIZE (buf, 0); | |
1926 | |
1927 /* Move the new gap down to be consecutive with the end of the old one. | |
1928 This adjusts the markers properly too. */ | |
1929 gap_left (buf, real_gap_loc + old_gap_size); | |
1930 | |
1931 /* Now combine the two into one large gap. */ | |
1932 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + old_gap_size); | |
1933 SET_BI_BUF_GPT (buf, real_gap_loc); | |
1934 SET_GAP_SENTINEL (buf); | |
1935 | |
1936 /* We changed the total size of the buffer (including gap), | |
1937 so we need to fix up the end sentinel. */ | |
1938 SET_END_SENTINEL (buf); | |
1939 | |
1940 Vinhibit_quit = tem; | |
1941 } | |
1942 | |
1943 | |
1944 /************************************************************************/ | |
1945 /* Before/after-change processing */ | |
1946 /************************************************************************/ | |
1947 | |
1948 /* Those magic changes ... */ | |
1949 | |
1950 static void | |
1951 buffer_signal_changed_region (struct buffer *buf, Bufpos start, | |
1952 Bufpos end) | |
1953 { | |
1954 /* The changed region is recorded as the number of unchanged | |
1955 characters from the beginning and from the end of the | |
1956 buffer. This obviates much of the need of shifting the | |
1957 region around to compensate for insertions and deletions. | |
1958 */ | |
1959 if (buf->changes->begin_unchanged < 0 || | |
1960 buf->changes->begin_unchanged > start - BUF_BEG (buf)) | |
1961 buf->changes->begin_unchanged = start - BUF_BEG (buf); | |
1962 if (buf->changes->end_unchanged < 0 || | |
1963 buf->changes->end_unchanged > BUF_Z (buf) - end) | |
1964 buf->changes->end_unchanged = BUF_Z (buf) - end; | |
1965 } | |
1966 | |
1967 void | |
1968 buffer_extent_signal_changed_region (struct buffer *buf, Bufpos start, | |
1969 Bufpos end) | |
1970 { | |
1971 if (buf->changes->begin_extent_unchanged < 0 || | |
1972 buf->changes->begin_extent_unchanged > start - BUF_BEG (buf)) | |
1973 buf->changes->begin_extent_unchanged = start - BUF_BEG (buf); | |
1974 if (buf->changes->end_extent_unchanged < 0 || | |
1975 buf->changes->end_extent_unchanged > BUF_Z (buf) - end) | |
1976 buf->changes->end_extent_unchanged = BUF_Z (buf) - end; | |
1977 } | |
1978 | |
1979 void | |
1980 buffer_reset_changes (struct buffer *buf) | |
1981 { | |
1982 buf->changes->begin_unchanged = -1; | |
1983 buf->changes->end_unchanged = -1; | |
1984 buf->changes->begin_extent_unchanged = -1; | |
1985 buf->changes->end_extent_unchanged = -1; | |
1986 buf->changes->newline_was_deleted = 0; | |
1987 } | |
1988 | |
1989 static void | |
1990 signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end, | |
1991 Bufpos new_end); | |
1992 | |
1993 | |
1994 /* Call the after-change-functions according to the changes made so far | |
1995 and treat all further changes as single until the outermost | |
1996 multiple change exits. This is called when the outermost multiple | |
1997 change exits and when someone is trying to make a change that violates | |
1998 the constraints specified in begin_multiple_change(), typically | |
1999 when nested multiple-change sessions occur. (There are smarter ways of | |
2000 dealing with nested multiple changes, but these rarely occur so there's | |
2001 probably no point in it.) */ | |
2002 | |
2003 /* #### This needs to keep track of what actually changed and only | |
2004 call the after-change functions on that region. */ | |
2005 | |
2006 static void | |
2007 cancel_multiple_change (struct buffer *buf) | |
2008 { | |
2009 /* This function can GC */ | |
2010 /* Call the after-change-functions except when they've already been | |
2011 called or when there were no changes made to the buffer at all. */ | |
2012 if (buf->text->changes->mc_begin != 0 && | |
2013 buf->text->changes->mc_begin_signaled) | |
2014 { | |
2015 Bufpos real_mc_begin = buf->text->changes->mc_begin; | |
2016 buf->text->changes->mc_begin = 0; | |
2017 | |
2018 signal_after_change (buf, real_mc_begin, buf->text->changes->mc_orig_end, | |
2019 buf->text->changes->mc_new_end); | |
2020 } | |
2021 else | |
2022 { | |
2023 buf->text->changes->mc_begin = 0; | |
2024 } | |
2025 } | |
2026 | |
2027 /* this is an unwind_protect, to ensure that the after-change-functions | |
2028 get called even in a non-local exit. */ | |
2029 | |
2030 static Lisp_Object | |
2031 multiple_change_finish_up (Lisp_Object buffer) | |
2032 { | |
2033 struct buffer *buf = XBUFFER (buffer); | |
2034 | |
2035 /* #### I don't know whether or not it should even be possible to | |
2036 get here with a dead buffer (though given how it is called I can | |
2037 see how it might be). In any case, there isn't time before 19.14 | |
2038 to find out. */ | |
2039 if (!BUFFER_LIVE_P (buf)) | |
2040 return Qnil; | |
2041 | |
2042 /* This function can GC */ | |
2043 buf->text->changes->in_multiple_change = 0; /* do this first so that | |
2044 errors in the after-change | |
2045 functions don't mess things | |
2046 up. */ | |
2047 cancel_multiple_change (buf); | |
2048 return Qnil; | |
2049 } | |
2050 | |
2051 /* Call this function when you're about to make a number of buffer changes | |
2052 that should be considered a single change. (e.g. `replace-match' calls | |
2053 this.) You need to specify the START and END of the region that is | |
2054 going to be changed so that the before-change-functions are called | |
2055 with the correct arguments. The after-change region is calculated | |
2056 automatically, however, and if changes somehow or other happen outside | |
2057 of the specified region, that will also be handled correctly. | |
2058 | |
2059 begin_multiple_change() returns a number (actually a specpdl depth) | |
2060 that you must pass to end_multiple_change() when you are done. */ | |
2061 | |
2062 int | |
2063 begin_multiple_change (struct buffer *buf, Bufpos start, Bufpos end) | |
2064 { | |
2065 /* This function can GC */ | |
2066 int count = -1; | |
2067 if (buf->text->changes->in_multiple_change) | |
2068 { | |
2069 if (buf->text->changes->mc_begin != 0 && | |
2070 (start < buf->text->changes->mc_begin || | |
2071 end > buf->text->changes->mc_new_end)) | |
2072 cancel_multiple_change (buf); | |
2073 } | |
2074 else | |
2075 { | |
2076 Lisp_Object buffer; | |
2077 | |
2078 buf->text->changes->mc_begin = start; | |
2079 buf->text->changes->mc_orig_end = buf->text->changes->mc_new_end = end; | |
2080 buf->text->changes->mc_begin_signaled = 0; | |
2081 count = specpdl_depth (); | |
2082 XSETBUFFER (buffer, buf); | |
2083 record_unwind_protect (multiple_change_finish_up, buffer); | |
2084 } | |
2085 buf->text->changes->in_multiple_change++; | |
2086 /* We don't call before-change-functions until signal_before_change() | |
2087 is called, in case there is a read-only or other error. */ | |
2088 return count; | |
2089 } | |
2090 | |
2091 void | |
2092 end_multiple_change (struct buffer *buf, int count) | |
2093 { | |
2094 assert (buf->text->changes->in_multiple_change > 0); | |
2095 buf->text->changes->in_multiple_change--; | |
2096 if (!buf->text->changes->in_multiple_change) | |
2097 unbind_to (count, Qnil); | |
2098 } | |
2099 | |
2100 static int inside_change_hook; | |
2101 | |
2102 static Lisp_Object | |
2103 change_function_restore (Lisp_Object buffer) | |
2104 { | |
2105 /* We should first reset the variable and then change the buffer, | |
2106 because Fset_buffer() can throw. */ | |
2107 inside_change_hook = 0; | |
2108 Fset_buffer (buffer); | |
2109 return Qnil; | |
2110 } | |
2111 | |
2112 static int in_first_change; | |
2113 | |
2114 static Lisp_Object | |
2115 first_change_hook_restore (Lisp_Object buffer) | |
2116 { | |
2117 in_first_change = 0; | |
2118 Fset_buffer (buffer); | |
2119 return Qnil; | |
2120 } | |
2121 | |
2122 /* Signal an initial modification to the buffer. */ | |
2123 | |
2124 static void | |
2125 signal_first_change (struct buffer *buf) | |
2126 { | |
2127 /* This function can GC */ | |
2128 Lisp_Object buffer; | |
2129 XSETBUFFER (buffer, current_buffer); | |
2130 | |
2131 if (!in_first_change) | |
2132 { | |
2133 if (!NILP (symbol_value_in_buffer (Qfirst_change_hook, buffer))) | |
2134 { | |
2135 int speccount = specpdl_depth (); | |
2136 record_unwind_protect (first_change_hook_restore, buffer); | |
2137 set_buffer_internal (buf); | |
2138 in_first_change = 1; | |
2139 run_hook (Qfirst_change_hook); | |
2140 unbind_to (speccount, Qnil); | |
2141 } | |
2142 } | |
2143 } | |
2144 | |
2145 /* Signal a change to the buffer immediately before it happens. | |
2146 START and END are the bounds of the text to be changed. */ | |
2147 | |
2148 static void | |
2149 signal_before_change (struct buffer *buf, Bufpos start, Bufpos end) | |
2150 { | |
2151 /* This function can GC */ | |
2152 struct buffer *mbuf; | |
2153 Lisp_Object bufcons; | |
2154 | |
2155 if (!inside_change_hook) | |
2156 { | |
2157 Lisp_Object buffer; | |
2158 | |
2159 /* Are we in a multiple-change session? */ | |
2160 if (buf->text->changes->in_multiple_change && | |
2161 buf->text->changes->mc_begin != 0) | |
2162 { | |
2163 /* If we're violating the constraints of the session, | |
2164 call the after-change-functions as necessary for the | |
2165 changes already made and treat further changes as | |
2166 single. */ | |
2167 if (start < buf->text->changes->mc_begin || | |
2168 end > buf->text->changes->mc_new_end) | |
2169 cancel_multiple_change (buf); | |
2170 /* Do nothing if this is not the first change in the session. */ | |
2171 else if (buf->text->changes->mc_begin_signaled) | |
2172 return; | |
2173 else | |
2174 { | |
2175 /* First time through; call the before-change-functions | |
2176 specifying the entire region to be changed. (Note that | |
2177 we didn't call before-change-functions in | |
2178 begin_multiple_change() because the buffer might be | |
2179 read-only, etc.) */ | |
2180 start = buf->text->changes->mc_begin; | |
2181 end = buf->text->changes->mc_new_end; | |
2182 } | |
2183 } | |
2184 | |
2185 /* If buffer is unmodified, run a special hook for that case. */ | |
2186 if (BUF_SAVE_MODIFF (buf) >= BUF_MODIFF (buf)) | |
2187 { | |
2188 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2189 { | |
2190 signal_first_change (mbuf); | |
2191 } | |
2192 } | |
2193 | |
2194 /* Now in any case run the before-change-functions if any. */ | |
2195 | |
2196 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2197 { | |
2198 XSETBUFFER (buffer, mbuf); | |
2199 if (!NILP (symbol_value_in_buffer (Qbefore_change_functions, buffer)) | |
2200 /* Obsolete, for compatibility */ | |
2201 || !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer))) | |
2202 { | |
2203 int speccount = specpdl_depth (); | |
2204 record_unwind_protect (change_function_restore, Fcurrent_buffer ()); | |
2205 set_buffer_internal (buf); | |
2206 inside_change_hook = 1; | |
2207 va_run_hook_with_args (Qbefore_change_functions, 2, | |
2208 make_int (start), make_int (end)); | |
2209 /* Obsolete, for compatibility */ | |
2210 va_run_hook_with_args (Qbefore_change_function, 2, | |
2211 make_int (start), make_int (end)); | |
2212 unbind_to (speccount, Qnil); | |
2213 } | |
2214 } | |
2215 | |
2216 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2217 { | |
2218 XSETBUFFER (buffer, mbuf); | |
2219 report_extent_modification (buffer, start, end, | |
2220 &inside_change_hook, 0); | |
2221 } | |
2222 | |
2223 /* Only now do we indicate that the before-change-functions have | |
2224 been called, in case some function throws out. */ | |
2225 buf->text->changes->mc_begin_signaled = 1; | |
2226 } | |
2227 } | |
2228 | |
2229 /* Signal a change immediately after it happens. | |
2230 START is the bufpos of the start of the changed text. | |
2231 ORIG_END is the bufpos of the end of the before-changed text. | |
2232 NEW_END is the bufpos of the end of the after-changed text. | |
2233 */ | |
2234 | |
2235 static void | |
2236 signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end, | |
2237 Bufpos new_end) | |
2238 { | |
2239 /* This function can GC */ | |
2240 struct buffer *mbuf; | |
2241 Lisp_Object bufcons; | |
2242 | |
2243 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2244 { | |
2245 /* always do this. */ | |
2246 buffer_signal_changed_region (mbuf, start, new_end); | |
2247 } | |
2248 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2249 { | |
2250 /* #### This seems inefficient. Wouldn't it be better to just | |
2251 keep one cache per base buffer? */ | |
2252 font_lock_maybe_update_syntactic_caches (mbuf, start, orig_end, new_end); | |
2253 } | |
2254 | |
2255 if (!inside_change_hook) | |
2256 { | |
2257 Lisp_Object buffer; | |
2258 | |
2259 if (buf->text->changes->in_multiple_change && | |
2260 buf->text->changes->mc_begin != 0) | |
2261 { | |
2262 assert (start >= buf->text->changes->mc_begin && | |
2263 start <= buf->text->changes->mc_new_end); | |
2264 assert (orig_end >= buf->text->changes->mc_begin && | |
2265 orig_end <= buf->text->changes->mc_new_end); | |
2266 buf->text->changes->mc_new_end += new_end - orig_end; | |
2267 return; /* after-change-functions signalled when all changes done */ | |
2268 } | |
2269 | |
2270 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2271 { | |
2272 XSETBUFFER (buffer, mbuf); | |
2273 | |
2274 if (!NILP (symbol_value_in_buffer (Qafter_change_functions, buffer)) | |
2275 /* Obsolete, for compatibility */ | |
2276 || !NILP (symbol_value_in_buffer (Qafter_change_function, buffer))) | |
2277 { | |
2278 int speccount = specpdl_depth (); | |
2279 record_unwind_protect (change_function_restore, Fcurrent_buffer ()); | |
2280 set_buffer_internal (buf); | |
2281 inside_change_hook = 1; | |
2282 /* The actual after-change functions take slightly | |
2283 different arguments than what we were passed. */ | |
2284 va_run_hook_with_args (Qafter_change_functions, 3, | |
2285 make_int (start), make_int (new_end), | |
2286 make_int (orig_end - start)); | |
2287 /* Obsolete, for compatibility */ | |
2288 va_run_hook_with_args (Qafter_change_function, 3, | |
2289 make_int (start), make_int (new_end), | |
2290 make_int (orig_end - start)); | |
2291 unbind_to (speccount, Qnil); | |
2292 } | |
2293 } | |
2294 | |
2295 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2296 { | |
2297 XSETBUFFER (buffer, mbuf); | |
2298 report_extent_modification (buffer, start, new_end, | |
2299 &inside_change_hook, 1); | |
2300 } | |
2301 } | |
2302 } | |
2303 | |
2304 /* Call this if you're about to change the region of BUFFER from START | |
2305 to END. This checks the read-only properties of the region, calls | |
2306 the necessary modification hooks, and warns the next redisplay that | |
2307 it should pay attention to that area. */ | |
2308 | |
2309 static void | |
2310 prepare_to_modify_buffer (struct buffer *buf, Bufpos start, Bufpos end, | |
2311 int lockit) | |
2312 { | |
2313 /* This function can GC */ | |
2314 /* dmoore - This function can also kill the buffer buf, the current | |
2315 buffer, and do anything it pleases. So if you call it, be | |
2316 careful. */ | |
2317 struct buffer *mbuf; | |
2318 Lisp_Object buffer, bufcons; | |
2319 struct gcpro gcpro1; | |
2320 | |
2321 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2322 { | |
2323 barf_if_buffer_read_only (mbuf, start, end); | |
2324 } | |
2325 | |
2326 /* if this is the first modification, see about locking the buffer's | |
2327 file */ | |
2328 XSETBUFFER (buffer, buf); | |
2329 GCPRO1 (buffer); | |
2330 if (!NILP (buf->filename) && lockit && | |
2331 BUF_SAVE_MODIFF (buf) >= BUF_MODIFF (buf)) | |
2332 { | |
2333 #ifdef CLASH_DETECTION | |
2334 if (!NILP (buf->file_truename)) | |
2335 /* Make binding buffer-file-name to nil effective. */ | |
2336 lock_file (buf->file_truename); | |
2337 #else | |
2338 /* At least warn if this file has changed on disk since it was visited.*/ | |
2339 if (NILP (Fverify_visited_file_modtime (buffer)) | |
2340 && !NILP (Ffile_exists_p (buf->filename))) | |
2341 call1_in_buffer (buf, intern ("ask-user-about-supersession-threat"), | |
2342 buf->filename); | |
2343 #endif /* not CLASH_DETECTION */ | |
2344 } | |
2345 UNGCPRO; | |
2346 | |
2347 /* #### dmoore - is this reasonable in case of buf being killed above? */ | |
2348 if (!BUFFER_LIVE_P (buf)) | |
2349 return; | |
2350 | |
2351 signal_before_change (buf, start, end); | |
2352 | |
2353 #ifdef REGION_CACHE_NEEDS_WORK | |
2354 if (buf->newline_cache) | |
2355 invalidate_region_cache (buf, | |
2356 buf->newline_cache, | |
2357 start - BUF_BEG (buf), BUF_Z (buf) - end); | |
2358 if (buf->width_run_cache) | |
2359 invalidate_region_cache (buf, | |
2360 buf->width_run_cache, | |
2361 start - BUF_BEG (buf), BUF_Z (buf) - end); | |
2362 #endif | |
2363 | |
2364 #if 0 /* FSFmacs */ | |
2365 Vdeactivate_mark = Qt; | |
2366 #endif | |
2367 | |
2368 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2369 { | |
2370 mbuf->point_before_scroll = Qnil; | |
2371 } | |
2372 } | |
2373 | |
2374 | |
2375 /************************************************************************/ | |
2376 /* Insertion of strings */ | |
2377 /************************************************************************/ | |
2378 | |
2379 void | |
2380 fixup_internal_substring (CONST Bufbyte *nonreloc, Lisp_Object reloc, | |
2381 Bytecount offset, Bytecount *len) | |
2382 { | |
2383 assert ((nonreloc && NILP (reloc)) || (!nonreloc && STRINGP (reloc))); | |
2384 | |
2385 if (*len < 0) | |
2386 { | |
2387 if (nonreloc) | |
2388 *len = strlen ((CONST char *) nonreloc) - offset; | |
2389 else | |
2390 *len = XSTRING_LENGTH (reloc) - offset; | |
2391 } | |
2392 #ifdef ERROR_CHECK_BUFPOS | |
2393 assert (*len >= 0); | |
2394 if (STRINGP (reloc)) | |
2395 { | |
2396 assert (offset >= 0 && offset <= XSTRING_LENGTH (reloc)); | |
2397 assert (offset + *len <= XSTRING_LENGTH (reloc)); | |
2398 } | |
2399 #endif | |
2400 } | |
2401 | |
2402 /* Insert a string into BUF at Bufpos POS. The string data comes | |
2403 from one of two sources: constant, non-relocatable data (specified | |
2404 in NONRELOC), or a Lisp string object (specified in RELOC), which | |
2405 is relocatable and may have extent data that needs to be copied | |
2406 into the buffer. OFFSET and LENGTH specify the substring of the | |
2407 data that is actually to be inserted. As a special case, if POS | |
2408 is -1, insert the string at point and move point to the end of the | |
2409 string. | |
2410 | |
2411 Normally, markers at the insertion point end up before the | |
2412 inserted string. If INSDEL_BEFORE_MARKERS is set in flags, however, | |
2413 they end up after the string. | |
2414 | |
2415 INSDEL_NO_LOCKING is kludgy and is used when insert-file-contents is | |
2416 visiting a new file; it inhibits the locking checks normally done | |
2417 before modifying a buffer. Similar checks were already done | |
2418 in the higher-level Lisp functions calling insert-file-contents. */ | |
2419 | |
2420 Charcount | |
2421 buffer_insert_string_1 (struct buffer *buf, Bufpos pos, | |
2422 CONST Bufbyte *nonreloc, Lisp_Object reloc, | |
2423 Bytecount offset, Bytecount length, | |
2424 int flags) | |
2425 { | |
2426 /* This function can GC */ | |
2427 struct gcpro gcpro1; | |
2428 Bytind ind; | |
2429 Charcount cclen; | |
2430 int move_point = 0; | |
2431 struct buffer *mbuf; | |
2432 Lisp_Object bufcons; | |
2433 | |
2434 /* Defensive steps just in case a buffer gets deleted and a calling | |
2435 function doesn't notice it. */ | |
2436 if (!BUFFER_LIVE_P (buf)) | |
2437 return 0; | |
2438 | |
2439 fixup_internal_substring (nonreloc, reloc, offset, &length); | |
2440 | |
2441 if (pos == -1) | |
2442 { | |
2443 pos = BUF_PT (buf); | |
2444 move_point = 1; | |
2445 } | |
2446 | |
2447 #ifdef I18N3 | |
2448 /* #### See the comment in print_internal(). If this buffer is marked | |
2449 as translatable, then Fgettext() should be called on obj if it | |
2450 is a string. */ | |
2451 #endif | |
2452 | |
2453 /* Make sure that point-max won't exceed the size of an emacs int. */ | |
2454 if ((length + BUF_Z (buf)) > EMACS_INT_MAX) | |
2455 error ("Maximum buffer size exceeded"); | |
2456 | |
2457 /* theoretically not necessary -- caller should GCPRO. | |
2458 #### buffer_insert_from_buffer_1() doesn't! */ | |
2459 GCPRO1 (reloc); | |
2460 | |
2461 prepare_to_modify_buffer (buf, pos, pos, !(flags & INSDEL_NO_LOCKING)); | |
2462 | |
2463 /* Defensive steps in case the before-change-functions fuck around */ | |
2464 if (!BUFFER_LIVE_P (buf)) | |
2465 { | |
2466 UNGCPRO; | |
2467 /* Bad bad pre-change function. */ | |
2468 return 0; | |
2469 } | |
2470 | |
2471 /* Make args be valid again. prepare_to_modify_buffer() might have | |
2472 modified the buffer. */ | |
2473 if (pos < BUF_BEGV (buf)) | |
2474 pos = BUF_BEGV (buf); | |
2475 if (pos > BUF_ZV (buf)) | |
2476 pos = BUF_ZV (buf); | |
2477 | |
2478 /* string may have been relocated up to this point */ | |
2479 if (STRINGP (reloc)) | |
2480 nonreloc = XSTRING_DATA (reloc); | |
2481 | |
2482 ind = bufpos_to_bytind (buf, pos); | |
2483 cclen = bytecount_to_charcount (nonreloc + offset, length); | |
2484 | |
2485 if (ind != BI_BUF_GPT (buf)) | |
2486 /* #### if debug-on-quit is invoked and the user changes the | |
2487 buffer, bad things can happen. This is a rampant problem | |
2488 in Emacs. */ | |
2489 move_gap (buf, ind); /* may QUIT */ | |
2490 if (! GAP_CAN_HOLD_SIZE_P (buf, length)) | |
2491 { | |
2492 if (BUF_END_GAP_SIZE (buf) >= length) | |
2493 merge_gap_with_end_gap (buf); | |
2494 else | |
2495 make_gap (buf, length - BUF_GAP_SIZE (buf)); | |
2496 } | |
2497 | |
2498 insert_invalidate_line_number_cache (buf, pos, nonreloc + offset, length); | |
2499 | |
2500 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2501 { | |
2502 record_insert (mbuf, pos, cclen); | |
2503 } | |
2504 | |
2505 BUF_MODIFF (buf)++; | |
2506 MARK_BUFFERS_CHANGED; | |
2507 | |
2508 /* string may have been relocated up to this point */ | |
2509 if (STRINGP (reloc)) | |
2510 nonreloc = XSTRING_DATA (reloc); | |
2511 | |
2512 memcpy (BUF_GPT_ADDR (buf), nonreloc + offset, length); | |
2513 | |
2514 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) - length); | |
2515 SET_BI_BUF_GPT (buf, BI_BUF_GPT (buf) + length); | |
2516 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2517 { | |
2518 SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) + cclen, BI_BUF_ZV (mbuf) + length); | |
2519 } | |
2520 SET_BOTH_BUF_Z (buf, BUF_Z (buf) + cclen, BI_BUF_Z (buf) + length); | |
2521 SET_GAP_SENTINEL (buf); | |
2522 | |
2523 #ifdef MULE | |
2524 buffer_mule_signal_inserted_region (buf, pos, length, cclen); | |
2525 #endif | |
2526 | |
2527 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2528 { | |
2529 process_extents_for_insertion (make_buffer (mbuf), ind, length); | |
2530 } | |
2531 | |
2532 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2533 { | |
2534 /* We know the gap is at IND so the cast is OK. */ | |
2535 adjust_markers_for_insert (mbuf, (Memind) ind, length); | |
2536 } | |
2537 | |
2538 /* Point logically doesn't move, but may need to be adjusted because | |
2539 it's a byte index. point-marker doesn't change because it's a | |
2540 memory index. */ | |
2541 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2542 { | |
2543 if (BI_BUF_PT (mbuf) > ind) | |
2544 JUST_SET_POINT (mbuf, BUF_PT (mbuf) + cclen, | |
2545 BI_BUF_PT (mbuf) + length); | |
2546 } | |
2547 | |
2548 /* Well, point might move. */ | |
2549 if (move_point) | |
2550 BI_BUF_SET_PT (buf, ind + length); | |
2551 | |
2552 if (STRINGP (reloc)) | |
2553 { | |
2554 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2555 { | |
2556 splice_in_string_extents (reloc, mbuf, ind, length, offset); | |
2557 } | |
2558 } | |
2559 | |
2560 if (flags & INSDEL_BEFORE_MARKERS) | |
2561 { | |
2562 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2563 { | |
2564 /* ind - 1 is correct because the FROM argument is exclusive. | |
2565 I formerly used DEC_BYTIND() but that caused problems at the | |
2566 beginning of the buffer. */ | |
2567 adjust_markers (mbuf, ind - 1, ind, length); | |
2568 } | |
2569 } | |
2570 | |
2571 signal_after_change (buf, pos, pos, pos + cclen); | |
2572 | |
2573 UNGCPRO; | |
2574 | |
2575 return cclen; | |
2576 } | |
2577 | |
2578 | |
2579 /* The following functions are interfaces onto the above function, | |
2580 for inserting particular sorts of data. In all the functions, | |
2581 BUF and POS specify the buffer and location where the insertion is | |
2582 to take place. (If POS is -1, text is inserted at point and point | |
2583 moves forward past the text.) FLAGS is as above. */ | |
2584 | |
2585 Charcount | |
2586 buffer_insert_raw_string_1 (struct buffer *buf, Bufpos pos, | |
2587 CONST Bufbyte *nonreloc, Bytecount length, | |
2588 int flags) | |
2589 { | |
2590 /* This function can GC */ | |
2591 return buffer_insert_string_1 (buf, pos, nonreloc, Qnil, 0, length, | |
2592 flags); | |
2593 } | |
2594 | |
2595 Charcount | |
2596 buffer_insert_lisp_string_1 (struct buffer *buf, Bufpos pos, Lisp_Object str, | |
2597 int flags) | |
2598 { | |
2599 /* This function can GC */ | |
2600 #ifdef ERROR_CHECK_TYPECHECK | |
2601 assert (STRINGP (str)); | |
2602 #endif | |
2603 return buffer_insert_string_1 (buf, pos, 0, str, 0, | |
2604 XSTRING_LENGTH (str), | |
2605 flags); | |
2606 } | |
2607 | |
2608 /* Insert the null-terminated string S (in external format). */ | |
2609 | |
2610 Charcount | |
2611 buffer_insert_c_string_1 (struct buffer *buf, Bufpos pos, CONST char *s, | |
2612 int flags) | |
2613 { | |
2614 /* This function can GC */ | |
2615 CONST char *translated = GETTEXT (s); | |
2616 return buffer_insert_string_1 (buf, pos, (CONST Bufbyte *) translated, Qnil, | |
2617 0, strlen (translated), flags); | |
2618 } | |
2619 | |
2620 Charcount | |
2621 buffer_insert_emacs_char_1 (struct buffer *buf, Bufpos pos, Emchar ch, | |
2622 int flags) | |
2623 { | |
2624 /* This function can GC */ | |
2625 Bufbyte str[MAX_EMCHAR_LEN]; | |
2626 Bytecount len = set_charptr_emchar (str, ch); | |
2627 return buffer_insert_string_1 (buf, pos, str, Qnil, 0, len, flags); | |
2628 } | |
2629 | |
2630 Charcount | |
2631 buffer_insert_c_char_1 (struct buffer *buf, Bufpos pos, char c, | |
2632 int flags) | |
2633 { | |
2634 /* This function can GC */ | |
2635 return buffer_insert_emacs_char_1 (buf, pos, (Emchar) (unsigned char) c, | |
2636 flags); | |
2637 } | |
2638 | |
2639 Charcount | |
2640 buffer_insert_from_buffer_1 (struct buffer *buf, Bufpos pos, | |
2641 struct buffer *buf2, Bufpos pos2, | |
2642 Charcount length, int flags) | |
2643 { | |
2644 /* This function can GC */ | |
2645 Lisp_Object str = make_string_from_buffer (buf2, pos2, length); | |
2646 return buffer_insert_string_1 (buf, pos, 0, str, 0, | |
2647 XSTRING_LENGTH (str), flags); | |
2648 } | |
2649 | |
2650 | |
2651 /************************************************************************/ | |
2652 /* Deletion of ranges */ | |
2653 /************************************************************************/ | |
2654 | |
2655 /* Delete characters in buffer from FROM up to (but not including) TO. */ | |
2656 | |
2657 void | |
2658 buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags) | |
2659 { | |
2660 /* This function can GC */ | |
2661 Charcount numdel; | |
2662 Bytind bi_from, bi_to; | |
2663 Bytecount bc_numdel; | |
2664 EMACS_INT shortage; | |
2665 struct buffer *mbuf; | |
2666 Lisp_Object bufcons; | |
2667 | |
2668 /* Defensive steps just in case a buffer gets deleted and a calling | |
2669 function doesn't notice it. */ | |
2670 if (!BUFFER_LIVE_P (buf)) | |
2671 return; | |
2672 | |
2673 /* Make args be valid */ | |
2674 if (from < BUF_BEGV (buf)) | |
2675 from = BUF_BEGV (buf); | |
2676 if (to > BUF_ZV (buf)) | |
2677 to = BUF_ZV (buf); | |
2678 if ((numdel = to - from) <= 0) | |
2679 return; | |
2680 | |
2681 prepare_to_modify_buffer (buf, from, to, !(flags & INSDEL_NO_LOCKING)); | |
2682 | |
2683 /* Defensive steps in case the before-change-functions fuck around */ | |
2684 if (!BUFFER_LIVE_P (buf)) | |
2685 /* Bad bad pre-change function. */ | |
2686 return; | |
2687 | |
2688 /* Make args be valid again. prepare_to_modify_buffer() might have | |
2689 modified the buffer. */ | |
2690 if (from < BUF_BEGV (buf)) | |
2691 from = BUF_BEGV (buf); | |
2692 if (to > BUF_ZV (buf)) | |
2693 to = BUF_ZV (buf); | |
2694 if ((numdel = to - from) <= 0) | |
2695 return; | |
2696 | |
2697 /* Redisplay needs to know if a newline was in the deleted region. | |
2698 If we've already marked the changed region as having a deleted | |
2699 newline there is no use in performing the check. */ | |
2700 if (!buf->changes->newline_was_deleted) | |
2701 { | |
2702 scan_buffer (buf, '\n', from, to, 1, &shortage, 1); | |
2703 if (!shortage) | |
2704 { | |
2705 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2706 { | |
2707 mbuf->changes->newline_was_deleted = 1; | |
2708 } | |
2709 } | |
2710 } | |
2711 | |
2712 bi_from = bufpos_to_bytind (buf, from); | |
2713 bi_to = bufpos_to_bytind (buf, to); | |
2714 bc_numdel = bi_to - bi_from; | |
2715 | |
2716 delete_invalidate_line_number_cache (buf, from, to); | |
2717 | |
2718 if (to == BUF_Z (buf) && | |
2719 bi_from > BI_BUF_GPT (buf)) | |
2720 { | |
2721 /* avoid moving the gap just to delete from the bottom. */ | |
2722 | |
2723 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2724 { | |
2725 record_delete (mbuf, from, numdel); | |
2726 } | |
2727 BUF_MODIFF (buf)++; | |
2728 MARK_BUFFERS_CHANGED; | |
2729 | |
2730 /* #### Point used to be modified here, but this causes problems | |
2731 with MULE, as point is used to calculate bytinds, and if the | |
2732 offset in bc_numdel causes point to move to a non first-byte | |
2733 location, causing some other function to throw an assertion | |
2734 in ASSERT_VALID_BYTIND. I've moved the code to right after | |
2735 the other movements and adjustments, but before the gap is | |
2736 moved. -- jh 970813 */ | |
2737 | |
2738 /* Detach any extents that are completely within the range [FROM, TO], | |
2739 if the extents are detachable. | |
2740 | |
2741 This must come AFTER record_delete(), so that the appropriate | |
2742 extents will be present to be recorded, and BEFORE the gap | |
2743 size is increased, as otherwise we will be confused about | |
2744 where the extents end. */ | |
2745 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2746 { | |
2747 process_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to, 0); | |
2748 } | |
2749 | |
2750 /* Relocate all markers pointing into the new, larger gap to | |
2751 point at the end of the text before the gap. */ | |
2752 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2753 { | |
2754 adjust_markers (mbuf, | |
2755 (bi_to + BUF_GAP_SIZE (mbuf)), | |
2756 (bi_to + BUF_GAP_SIZE (mbuf)), | |
2757 (- bc_numdel)); | |
2758 } | |
2759 | |
2760 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2761 { | |
2762 /* Relocate any extent endpoints just like markers. */ | |
2763 adjust_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to, | |
2764 BUF_GAP_SIZE (mbuf), bc_numdel, 0); | |
2765 } | |
2766 | |
2767 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2768 { | |
2769 /* Relocate point as if it were a marker. */ | |
2770 if (bi_from < BI_BUF_PT (mbuf)) | |
2771 { | |
2772 if (BI_BUF_PT (mbuf) < bi_to) | |
2773 JUST_SET_POINT (mbuf, from, bi_from); | |
2774 else | |
2775 JUST_SET_POINT (mbuf, BUF_PT (mbuf) - numdel, | |
2776 BI_BUF_PT (mbuf) - bc_numdel); | |
2777 } | |
2778 } | |
2779 | |
2780 SET_BUF_END_GAP_SIZE (buf, BUF_END_GAP_SIZE (buf) + bc_numdel); | |
2781 | |
2782 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2783 { | |
2784 SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) - numdel, | |
2785 BI_BUF_ZV (mbuf) - bc_numdel); | |
2786 } | |
2787 SET_BOTH_BUF_Z (buf, BUF_Z (buf) - numdel, BI_BUF_Z (buf) - bc_numdel); | |
2788 SET_GAP_SENTINEL (buf); | |
2789 } | |
2790 else | |
2791 { | |
2792 /* Make sure the gap is somewhere in or next to what we are deleting. */ | |
2793 if (bi_to < BI_BUF_GPT (buf)) | |
2794 gap_left (buf, bi_to); | |
2795 if (bi_from > BI_BUF_GPT (buf)) | |
2796 gap_right (buf, bi_from); | |
2797 | |
2798 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2799 { | |
2800 record_delete (mbuf, from, numdel); | |
2801 } | |
2802 BUF_MODIFF (buf)++; | |
2803 MARK_BUFFERS_CHANGED; | |
2804 | |
2805 /* #### Point used to be modified here, but this causes problems | |
2806 with MULE, as point is used to calculate bytinds, and if the | |
2807 offset in bc_numdel causes point to move to a non first-byte | |
2808 location, causing some other function to throw an assertion | |
2809 in ASSERT_VALID_BYTIND. I've moved the code to right after | |
2810 the other movements and adjustments, but before the gap is | |
2811 moved. -- jh 970813 */ | |
2812 | |
2813 /* Detach any extents that are completely within the range [FROM, TO], | |
2814 if the extents are detachable. | |
2815 | |
2816 This must come AFTER record_delete(), so that the appropriate extents | |
2817 will be present to be recorded, and BEFORE the gap size is increased, | |
2818 as otherwise we will be confused about where the extents end. */ | |
2819 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2820 { | |
2821 process_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to, 0); | |
2822 } | |
2823 | |
2824 /* Relocate all markers pointing into the new, larger gap to | |
2825 point at the end of the text before the gap. */ | |
2826 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2827 { | |
2828 adjust_markers (mbuf, | |
2829 (bi_to + BUF_GAP_SIZE (mbuf)), | |
2830 (bi_to + BUF_GAP_SIZE (mbuf)), | |
2831 (- bc_numdel - BUF_GAP_SIZE (mbuf))); | |
2832 } | |
2833 | |
2834 /* Relocate any extent endpoints just like markers. */ | |
2835 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2836 { | |
2837 adjust_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to, | |
2838 BUF_GAP_SIZE (mbuf), | |
2839 bc_numdel, BUF_GAP_SIZE (mbuf)); | |
2840 } | |
2841 | |
2842 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2843 { | |
2844 /* Relocate point as if it were a marker. */ | |
2845 if (bi_from < BI_BUF_PT (mbuf)) | |
2846 { | |
2847 if (BI_BUF_PT (mbuf) < bi_to) | |
2848 JUST_SET_POINT (mbuf, from, bi_from); | |
2849 else | |
2850 JUST_SET_POINT (mbuf, BUF_PT (mbuf) - numdel, | |
2851 BI_BUF_PT (mbuf) - bc_numdel); | |
2852 } | |
2853 } | |
2854 | |
2855 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + bc_numdel); | |
2856 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2857 { | |
2858 SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) - numdel, | |
2859 BI_BUF_ZV (mbuf) - bc_numdel); | |
2860 } | |
2861 SET_BOTH_BUF_Z (buf, BUF_Z (buf) - numdel, BI_BUF_Z (buf) - bc_numdel); | |
2862 SET_BI_BUF_GPT (buf, bi_from); | |
2863 SET_GAP_SENTINEL (buf); | |
2864 } | |
2865 | |
2866 #ifdef MULE | |
2867 buffer_mule_signal_deleted_region (buf, from, to, bi_from, bi_to); | |
2868 #endif | |
2869 | |
2870 #ifdef ERROR_CHECK_EXTENTS | |
2871 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2872 { | |
2873 sledgehammer_extent_check (make_buffer (mbuf)); | |
2874 } | |
2875 #endif | |
2876 | |
2877 signal_after_change (buf, from, to, from); | |
2878 } | |
2879 | |
2880 | |
2881 /************************************************************************/ | |
2882 /* Replacement of characters */ | |
2883 /************************************************************************/ | |
2884 | |
2885 /* Replace the character at POS in buffer B with CH. */ | |
2886 | |
2887 void | |
2888 buffer_replace_char (struct buffer *buf, Bufpos pos, Emchar ch, | |
2889 int not_real_change, int force_lock_check) | |
2890 { | |
2891 /* This function can GC */ | |
2892 Bufbyte curstr[MAX_EMCHAR_LEN]; | |
2893 Bufbyte newstr[MAX_EMCHAR_LEN]; | |
2894 Bytecount curlen, newlen; | |
2895 | |
2896 /* Defensive steps just in case a buffer gets deleted and a calling | |
2897 function doesn't notice it. */ | |
2898 if (!BUFFER_LIVE_P (buf)) | |
2899 return; | |
2900 | |
2901 curlen = BUF_CHARPTR_COPY_CHAR (buf, pos, curstr); | |
2902 newlen = set_charptr_emchar (newstr, ch); | |
2903 | |
2904 if (curlen == newlen) | |
2905 { | |
2906 struct buffer *mbuf; | |
2907 Lisp_Object bufcons; | |
2908 | |
2909 /* then we can just replace the text. */ | |
2910 prepare_to_modify_buffer (buf, pos, pos + 1, | |
2911 !not_real_change || force_lock_check); | |
2912 /* Defensive steps in case the before-change-functions fuck around */ | |
2913 if (!BUFFER_LIVE_P (buf)) | |
2914 /* Bad bad pre-change function. */ | |
2915 return; | |
2916 | |
2917 /* Make args be valid again. prepare_to_modify_buffer() might have | |
2918 modified the buffer. */ | |
2919 if (pos < BUF_BEGV (buf)) | |
2920 pos = BUF_BEGV (buf); | |
2921 if (pos >= BUF_ZV (buf)) | |
2922 pos = BUF_ZV (buf) - 1; | |
2923 if (pos < BUF_BEGV (buf)) | |
2924 /* no more characters in buffer! */ | |
2925 return; | |
2926 | |
2927 if (BUF_FETCH_CHAR (buf, pos) == '\n') | |
2928 { | |
2929 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2930 { | |
2931 mbuf->changes->newline_was_deleted = 1; | |
2932 } | |
2933 } | |
2934 MARK_BUFFERS_CHANGED; | |
2935 if (!not_real_change) | |
2936 { | |
2937 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) | |
2938 { | |
2939 record_change (mbuf, pos, 1); | |
2940 } | |
2941 BUF_MODIFF (buf)++; | |
2942 } | |
2943 memcpy (BUF_BYTE_ADDRESS (buf, pos), newstr, newlen); | |
2944 | |
2945 signal_after_change (buf, pos, pos + 1, pos + 1); | |
2946 | |
2947 /* We do not have to adjust the Mule data; we just replaced a | |
2948 character with another of the same number of bytes. */ | |
2949 } | |
2950 else | |
2951 { | |
2952 /* | |
2953 * Must implement as deletion followed by insertion. | |
2954 * | |
2955 * Make a note to move point forward later in the one situation | |
2956 * where it is needed, a delete/insert one position behind | |
2957 * point. Point will drift backward by one position and stay | |
2958 * there otherwise. | |
2959 */ | |
2960 int movepoint = (pos == BUF_PT (buf) - 1); | |
2961 | |
2962 buffer_delete_range (buf, pos, pos + 1, 0); | |
2963 /* Defensive steps in case the before-change-functions fuck around */ | |
2964 if (!BUFFER_LIVE_P (buf)) | |
2965 /* Bad bad pre-change function. */ | |
2966 return; | |
2967 | |
2968 /* Make args be valid again. prepare_to_modify_buffer() might have | |
2969 modified the buffer. */ | |
2970 if (pos < BUF_BEGV (buf)) | |
2971 pos = BUF_BEGV (buf); | |
2972 if (pos >= BUF_ZV (buf)) | |
2973 pos = BUF_ZV (buf) - 1; | |
2974 if (pos < BUF_BEGV (buf)) | |
2975 /* no more characters in buffer! */ | |
2976 return; | |
2977 /* | |
2978 * -1 as the pos argument means to move point forward with the | |
2979 * insertion, which we must do if the deletion moved point | |
2980 * backward so that it now equals the insertion point. | |
2981 */ | |
2982 buffer_insert_string_1 (buf, (movepoint ? -1 : pos), | |
2983 newstr, Qnil, 0, newlen, 0); | |
2984 } | |
2985 } | |
2986 | |
2987 | |
2988 /************************************************************************/ | |
2989 /* Other functions */ | |
2990 /************************************************************************/ | |
2991 | |
2992 /* Make a string from a buffer. This needs to take into account the gap, | |
2993 and add any necessary extents from the buffer. */ | |
2994 | |
2995 static Lisp_Object | |
2996 make_string_from_buffer_1 (struct buffer *buf, Bufpos pos, Charcount length, | |
2997 int no_extents) | |
2998 { | |
2999 /* This function can GC */ | |
3000 Bytind bi_ind = bufpos_to_bytind (buf, pos); | |
3001 Bytecount bi_len = bufpos_to_bytind (buf, pos + length) - bi_ind; | |
3002 Lisp_Object val = make_uninit_string (bi_len); | |
3003 | |
3004 struct gcpro gcpro1; | |
3005 GCPRO1 (val); | |
3006 | |
3007 if (!no_extents) | |
3008 add_string_extents (val, buf, bi_ind, bi_len); | |
3009 | |
3010 { | |
3011 Bytecount len1 = BI_BUF_GPT (buf) - bi_ind; | |
3012 Bufbyte *start1 = BI_BUF_BYTE_ADDRESS (buf, bi_ind); | |
3013 Bufbyte *dest = XSTRING_DATA (val); | |
3014 | |
3015 if (len1 < 0) | |
3016 { | |
3017 /* Completely after gap */ | |
3018 memcpy (dest, start1, bi_len); | |
3019 } | |
3020 else if (bi_len <= len1) | |
3021 { | |
3022 /* Completely before gap */ | |
3023 memcpy (dest, start1, bi_len); | |
3024 } | |
3025 else | |
3026 { | |
3027 /* Spans gap */ | |
3028 Bytind pos2 = bi_ind + len1; | |
3029 Bufbyte *start2 = BI_BUF_BYTE_ADDRESS (buf, pos2); | |
3030 | |
3031 memcpy (dest, start1, len1); | |
3032 memcpy (dest + len1, start2, bi_len - len1); | |
3033 } | |
3034 } | |
3035 | |
3036 UNGCPRO; | |
3037 return val; | |
3038 } | |
3039 | |
3040 Lisp_Object | |
3041 make_string_from_buffer (struct buffer *buf, Bufpos pos, Charcount length) | |
3042 { | |
3043 return make_string_from_buffer_1 (buf, pos, length, 0); | |
3044 } | |
3045 | |
3046 Lisp_Object | |
3047 make_string_from_buffer_no_extents (struct buffer *buf, Bufpos pos, | |
3048 Charcount length) | |
3049 { | |
3050 return make_string_from_buffer_1 (buf, pos, length, 1); | |
3051 } | |
3052 | |
3053 void | |
3054 barf_if_buffer_read_only (struct buffer *buf, Bufpos from, Bufpos to) | |
3055 { | |
3056 Lisp_Object buffer; | |
3057 Lisp_Object iro; | |
3058 | |
3059 XSETBUFFER (buffer, buf); | |
3060 back: | |
3061 iro = (buf == current_buffer ? Vinhibit_read_only : | |
3062 symbol_value_in_buffer (Qinhibit_read_only, buffer)); | |
3063 if (!LISTP (iro)) | |
3064 return; | |
3065 if (NILP (iro) && !NILP (buf->read_only)) | |
3066 { | |
3067 Fsignal (Qbuffer_read_only, (list1 (buffer))); | |
3068 goto back; | |
3069 } | |
3070 if (from > 0) | |
3071 { | |
3072 if (to < 0) | |
3073 to = from; | |
3074 verify_extent_modification (buffer, | |
3075 bufpos_to_bytind (buf, from), | |
3076 bufpos_to_bytind (buf, to), | |
3077 iro); | |
3078 } | |
3079 } | |
3080 | |
3081 void | |
3082 find_charsets_in_bufbyte_string (unsigned char *charsets, CONST Bufbyte *str, | |
3083 Bytecount len) | |
3084 { | |
3085 #ifndef MULE | |
3086 /* Telescope this. */ | |
3087 charsets[0] = 1; | |
3088 #else | |
3089 CONST Bufbyte *strend = str + len; | |
3090 memset (charsets, 0, NUM_LEADING_BYTES); | |
3091 | |
3092 while (str < strend) | |
3093 { | |
3094 charsets[CHAR_LEADING_BYTE (charptr_emchar (str)) - 128] = 1; | |
3095 INC_CHARPTR (str); | |
3096 } | |
3097 #endif | |
3098 } | |
3099 | |
3100 void | |
3101 find_charsets_in_emchar_string (unsigned char *charsets, CONST Emchar *str, | |
3102 Charcount len) | |
3103 { | |
3104 #ifndef MULE | |
3105 /* Telescope this. */ | |
3106 charsets[0] = 1; | |
3107 #else | |
3108 int i; | |
3109 | |
3110 memset (charsets, 0, NUM_LEADING_BYTES); | |
3111 for (i = 0; i < len; i++) | |
3112 { | |
3113 charsets[CHAR_LEADING_BYTE (str[i]) - 128] = 1; | |
3114 } | |
3115 #endif | |
3116 } | |
3117 | |
3118 int | |
3119 bufbyte_string_displayed_columns (CONST Bufbyte *str, Bytecount len) | |
3120 { | |
3121 int cols = 0; | |
3122 CONST Bufbyte *end = str + len; | |
3123 | |
3124 while (str < end) | |
3125 { | |
3126 #ifdef MULE | |
3127 Emchar ch = charptr_emchar (str); | |
3128 cols += XCHARSET_COLUMNS (CHAR_CHARSET (ch)); | |
3129 #else | |
3130 cols++; | |
3131 #endif | |
3132 INC_CHARPTR (str); | |
3133 } | |
3134 | |
3135 return cols; | |
3136 } | |
3137 | |
3138 int | |
3139 emchar_string_displayed_columns (CONST Emchar *str, Charcount len) | |
3140 { | |
3141 #ifdef MULE | |
3142 int cols = 0; | |
3143 int i; | |
3144 | |
3145 for (i = 0; i < len; i++) | |
3146 cols += XCHARSET_COLUMNS (CHAR_CHARSET (str[i])); | |
3147 | |
3148 return cols; | |
3149 #else /* not MULE */ | |
3150 return len; | |
3151 #endif | |
3152 } | |
3153 | |
3154 /* NOTE: Does not reset the Dynarr. */ | |
3155 | |
3156 void | |
3157 convert_bufbyte_string_into_emchar_dynarr (CONST Bufbyte *str, Bytecount len, | |
3158 Emchar_dynarr *dyn) | |
3159 { | |
3160 CONST Bufbyte *strend = str + len; | |
3161 | |
3162 while (str < strend) | |
3163 { | |
3164 Emchar ch = charptr_emchar (str); | |
3165 Dynarr_add (dyn, ch); | |
3166 INC_CHARPTR (str); | |
3167 } | |
3168 } | |
3169 | |
3170 Charcount | |
3171 convert_bufbyte_string_into_emchar_string (CONST Bufbyte *str, Bytecount len, | |
3172 Emchar *arr) | |
3173 { | |
3174 CONST Bufbyte *strend = str + len; | |
3175 Charcount newlen = 0; | |
3176 while (str < strend) | |
3177 { | |
3178 Emchar ch = charptr_emchar (str); | |
3179 arr[newlen++] = ch; | |
3180 INC_CHARPTR (str); | |
3181 } | |
3182 return newlen; | |
3183 } | |
3184 | |
3185 /* Convert an array of Emchars into the equivalent string representation. | |
3186 Store into the given Bufbyte dynarr. Does not reset the dynarr. | |
3187 Does not add a terminating zero. */ | |
3188 | |
3189 void | |
3190 convert_emchar_string_into_bufbyte_dynarr (Emchar *arr, int nels, | |
3191 Bufbyte_dynarr *dyn) | |
3192 { | |
3193 Bufbyte str[MAX_EMCHAR_LEN]; | |
3194 int i; | |
3195 | |
3196 for (i = 0; i < nels; i++) | |
3197 { | |
3198 Bytecount len = set_charptr_emchar (str, arr[i]); | |
3199 Dynarr_add_many (dyn, str, len); | |
3200 } | |
3201 } | |
3202 | |
3203 /* Convert an array of Emchars into the equivalent string representation. | |
3204 Malloc the space needed for this and return it. If LEN_OUT is not a | |
3205 NULL pointer, store into LEN_OUT the number of Bufbytes in the | |
3206 malloc()ed string. Note that the actual number of Bufbytes allocated | |
3207 is one more than this: the returned string is zero-terminated. */ | |
3208 | |
3209 Bufbyte * | |
3210 convert_emchar_string_into_malloced_string (Emchar *arr, int nels, | |
3211 Bytecount *len_out) | |
3212 { | |
3213 /* Damn zero-termination. */ | |
3214 Bufbyte *str = (Bufbyte *) alloca (nels * MAX_EMCHAR_LEN + 1); | |
3215 Bufbyte *strorig = str; | |
3216 Bytecount len; | |
3217 | |
3218 int i; | |
3219 | |
3220 for (i = 0; i < nels; i++) | |
3221 str += set_charptr_emchar (str, arr[i]); | |
3222 *str = '\0'; | |
3223 len = str - strorig; | |
3224 str = (Bufbyte *) xmalloc (1 + len); | |
3225 memcpy (str, strorig, 1 + len); | |
3226 if (len_out) | |
3227 *len_out = len; | |
3228 return str; | |
3229 } | |
3230 | |
3231 | |
3232 /************************************************************************/ | |
3233 /* initialization */ | |
3234 /************************************************************************/ | |
3235 | |
3236 void | |
3237 reinit_vars_of_insdel (void) | |
3238 { | |
3239 int i; | |
3240 | |
3241 inside_change_hook = 0; | |
3242 in_first_change = 0; | |
3243 | |
3244 for (i = 0; i <= MAX_BYTIND_GAP_SIZE_3; i++) | |
3245 three_to_one_table[i] = i / 3; | |
3246 } | |
3247 | |
3248 void | |
3249 vars_of_insdel (void) | |
3250 { | |
3251 reinit_vars_of_insdel (); | |
3252 } | |
3253 | |
3254 void | |
3255 init_buffer_text (struct buffer *b) | |
3256 { | |
3257 if (!b->base_buffer) | |
3258 { | |
3259 SET_BUF_GAP_SIZE (b, 20); | |
3260 BUFFER_ALLOC (b->text->beg, BUF_GAP_SIZE (b) + BUF_END_SENTINEL_SIZE); | |
3261 if (! BUF_BEG_ADDR (b)) | |
3262 memory_full (); | |
3263 | |
3264 SET_BUF_END_GAP_SIZE (b, 0); | |
3265 SET_BI_BUF_GPT (b, 1); | |
3266 SET_BOTH_BUF_Z (b, 1, 1); | |
3267 SET_GAP_SENTINEL (b); | |
3268 SET_END_SENTINEL (b); | |
3269 #ifdef MULE | |
3270 { | |
3271 int i; | |
3272 | |
3273 b->text->mule_bufmin = b->text->mule_bufmax = 1; | |
3274 b->text->mule_bytmin = b->text->mule_bytmax = 1; | |
3275 b->text->mule_shifter = 0; | |
3276 b->text->mule_three_p = 0; | |
3277 | |
3278 for (i = 0; i < 16; i++) | |
3279 { | |
3280 b->text->mule_bufpos_cache[i] = 1; | |
3281 b->text->mule_bytind_cache[i] = 1; | |
3282 } | |
3283 } | |
3284 #endif /* MULE */ | |
3285 b->text->line_number_cache = Qnil; | |
3286 | |
3287 BUF_MODIFF (b) = 1; | |
3288 BUF_SAVE_MODIFF (b) = 1; | |
3289 | |
3290 JUST_SET_POINT (b, 1, 1); | |
3291 SET_BOTH_BUF_BEGV (b, 1, 1); | |
3292 SET_BOTH_BUF_ZV (b, 1, 1); | |
3293 | |
3294 b->text->changes = xnew_and_zero (struct buffer_text_change_data); | |
3295 } | |
3296 else | |
3297 { | |
3298 JUST_SET_POINT (b, BUF_PT (b->base_buffer), BI_BUF_PT (b->base_buffer)); | |
3299 SET_BOTH_BUF_BEGV (b, BUF_BEGV (b->base_buffer), | |
3300 BI_BUF_BEGV (b->base_buffer)); | |
3301 SET_BOTH_BUF_ZV (b, BUF_ZV (b->base_buffer), | |
3302 BI_BUF_ZV (b->base_buffer)); | |
3303 } | |
3304 | |
3305 b->changes = xnew_and_zero (struct each_buffer_change_data); | |
3306 BUF_FACECHANGE (b) = 1; | |
3307 | |
3308 #ifdef REGION_CACHE_NEEDS_WORK | |
3309 b->newline_cache = 0; | |
3310 b->width_run_cache = 0; | |
3311 b->width_table = Qnil; | |
3312 #endif | |
3313 } | |
3314 | |
3315 void | |
3316 uninit_buffer_text (struct buffer *b) | |
3317 { | |
3318 if (!b->base_buffer) | |
3319 { | |
3320 BUFFER_FREE (b->text->beg); | |
3321 xfree (b->text->changes); | |
3322 } | |
3323 xfree (b->changes); | |
3324 | |
3325 #ifdef REGION_CACHE_NEEDS_WORK | |
3326 if (b->newline_cache) | |
3327 { | |
3328 free_region_cache (b->newline_cache); | |
3329 b->newline_cache = 0; | |
3330 } | |
3331 if (b->width_run_cache) | |
3332 { | |
3333 free_region_cache (b->width_run_cache); | |
3334 b->width_run_cache = 0; | |
3335 } | |
3336 b->width_table = Qnil; | |
3337 #endif | |
3338 } |