aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2011-11-18 11:00:40 -0500
committerStefan Monnier2011-11-18 11:00:40 -0500
commitb50a28de8707794ff4b4b755af3173cd19004976 (patch)
treeb8d300d66b7c1046ff39e67fb332722181148f61 /src
parent6944dbc18a1591bc7435193685db90a6b9343914 (diff)
downloademacs-b50a28de8707794ff4b4b755af3173cd19004976.tar.gz
emacs-b50a28de8707794ff4b4b755af3173cd19004976.zip
* src/intervals.c: Fix grafting over the whole buffer.
(graft_intervals_into_buffer): Simplify. Fixes: debbugs:10071
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog7
-rw-r--r--src/insdel.c2
-rw-r--r--src/intervals.c41
-rw-r--r--src/intervals.h68
4 files changed, 53 insertions, 65 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 9af953b08b1..199f20817ea 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
12011-11-18 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * intervals.c: Fix grafting over the whole buffer (bug#10071).
4 (graft_intervals_into_buffer): Simplify.
5
12011-11-18 Eli Zaretskii <eliz@gnu.org> 62011-11-18 Eli Zaretskii <eliz@gnu.org>
2 7
3 * dispnew.c (swap_glyph_pointers): Swap the used[] arrays and the 8 * dispnew.c (swap_glyph_pointers): Swap the used[] arrays and the
@@ -394,7 +399,7 @@
394 399
395 Fix the `xbytecode' command. 400 Fix the `xbytecode' command.
396 * .gdbinit (xprintbytestr): New command. 401 * .gdbinit (xprintbytestr): New command.
397 (xwhichsymbols): Renamed from `which'; all callers changed. 402 (xwhichsymbols): Rename from `which'; all callers changed.
398 (xbytecode): Print the byte-code string as well. 403 (xbytecode): Print the byte-code string as well.
399 404
4002011-10-29 Kim Storm <storm@cua.dk> 4052011-10-29 Kim Storm <storm@cua.dk>
diff --git a/src/insdel.c b/src/insdel.c
index 01e5c57b2b0..e39a362eac7 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -1316,7 +1316,7 @@ replace_range (EMACS_INT from, EMACS_INT to, Lisp_Object new,
1316 1316
1317 UNGCPRO; 1317 UNGCPRO;
1318 1318
1319 /* Make args be valid */ 1319 /* Make args be valid. */
1320 if (from < BEGV) 1320 if (from < BEGV)
1321 from = BEGV; 1321 from = BEGV;
1322 if (to > ZV) 1322 if (to > ZV)
diff --git a/src/intervals.c b/src/intervals.c
index a78c7f07f6c..35d05d021f0 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -1317,7 +1317,7 @@ interval_deletion_adjustment (register INTERVAL tree, register EMACS_INT from,
1317 if (NULL_INTERVAL_P (tree)) 1317 if (NULL_INTERVAL_P (tree))
1318 return 0; 1318 return 0;
1319 1319
1320 /* Left branch */ 1320 /* Left branch. */
1321 if (relative_position < LEFT_TOTAL_LENGTH (tree)) 1321 if (relative_position < LEFT_TOTAL_LENGTH (tree))
1322 { 1322 {
1323 EMACS_INT subtract = interval_deletion_adjustment (tree->left, 1323 EMACS_INT subtract = interval_deletion_adjustment (tree->left,
@@ -1327,7 +1327,7 @@ interval_deletion_adjustment (register INTERVAL tree, register EMACS_INT from,
1327 CHECK_TOTAL_LENGTH (tree); 1327 CHECK_TOTAL_LENGTH (tree);
1328 return subtract; 1328 return subtract;
1329 } 1329 }
1330 /* Right branch */ 1330 /* Right branch. */
1331 else if (relative_position >= (TOTAL_LENGTH (tree) 1331 else if (relative_position >= (TOTAL_LENGTH (tree)
1332 - RIGHT_TOTAL_LENGTH (tree))) 1332 - RIGHT_TOTAL_LENGTH (tree)))
1333 { 1333 {
@@ -1699,54 +1699,37 @@ graft_intervals_into_buffer (INTERVAL source, EMACS_INT position,
1699 Qnil, buf, 0); 1699 Qnil, buf, 0);
1700 } 1700 }
1701 if (! NULL_INTERVAL_P (BUF_INTERVALS (buffer))) 1701 if (! NULL_INTERVAL_P (BUF_INTERVALS (buffer)))
1702 /* Shouldn't be necessary. -stef */ 1702 /* Shouldn't be necessary. --Stef */
1703 BUF_INTERVALS (buffer) = balance_an_interval (BUF_INTERVALS (buffer)); 1703 BUF_INTERVALS (buffer) = balance_an_interval (BUF_INTERVALS (buffer));
1704 return; 1704 return;
1705 } 1705 }
1706 1706
1707 if (NULL_INTERVAL_P (tree)) 1707 eassert (length == TOTAL_LENGTH (source));
1708 { 1708
1709 /* The inserted text constitutes the whole buffer, so 1709 if ((BUF_Z (buffer) - BUF_BEG (buffer)) == length)
1710 { /* The inserted text constitutes the whole buffer, so
1710 simply copy over the interval structure. */ 1711 simply copy over the interval structure. */
1711 if ((BUF_Z (buffer) - BUF_BEG (buffer)) == TOTAL_LENGTH (source))
1712 {
1713 Lisp_Object buf; 1712 Lisp_Object buf;
1714 XSETBUFFER (buf, buffer); 1713 XSETBUFFER (buf, buffer);
1715 BUF_INTERVALS (buffer) = reproduce_tree_obj (source, buf); 1714 BUF_INTERVALS (buffer) = reproduce_tree_obj (source, buf);
1716 BUF_INTERVALS (buffer)->position = BEG; 1715 BUF_INTERVALS (buffer)->position = BUF_BEG (buffer);
1717 BUF_INTERVALS (buffer)->up_obj = 1; 1716 eassert (BUF_INTERVALS (buffer)->up_obj == 1);
1718
1719 return; 1717 return;
1720 } 1718 }
1721 1719 else if (NULL_INTERVAL_P (tree))
1722 /* Create an interval tree in which to place a copy 1720 { /* Create an interval tree in which to place a copy
1723 of the intervals of the inserted string. */ 1721 of the intervals of the inserted string. */
1724 {
1725 Lisp_Object buf; 1722 Lisp_Object buf;
1726 XSETBUFFER (buf, buffer); 1723 XSETBUFFER (buf, buffer);
1727 tree = create_root_interval (buf); 1724 tree = create_root_interval (buf);
1728 } 1725 }
1729 }
1730 else if (TOTAL_LENGTH (tree) == TOTAL_LENGTH (source))
1731 /* If the buffer contains only the new string, but
1732 there was already some interval tree there, then it may be
1733 some zero length intervals. Eventually, do something clever
1734 about inserting properly. For now, just waste the old intervals. */
1735 {
1736 BUF_INTERVALS (buffer) = reproduce_tree (source, INTERVAL_PARENT (tree));
1737 BUF_INTERVALS (buffer)->position = BEG;
1738 BUF_INTERVALS (buffer)->up_obj = 1;
1739 /* Explicitly free the old tree here. */
1740
1741 return;
1742 }
1743 /* Paranoia -- the text has already been added, so this buffer 1726 /* Paranoia -- the text has already been added, so this buffer
1744 should be of non-zero length. */ 1727 should be of non-zero length. */
1745 else if (TOTAL_LENGTH (tree) == 0) 1728 else if (TOTAL_LENGTH (tree) == 0)
1746 abort (); 1729 abort ();
1747 1730
1748 this = under = find_interval (tree, position); 1731 this = under = find_interval (tree, position);
1749 if (NULL_INTERVAL_P (under)) /* Paranoia */ 1732 if (NULL_INTERVAL_P (under)) /* Paranoia. */
1750 abort (); 1733 abort ();
1751 over = find_interval (source, interval_start_pos (source)); 1734 over = find_interval (source, interval_start_pos (source));
1752 1735
diff --git a/src/intervals.h b/src/intervals.h
index 720598fe7a6..977f3d965a4 100644
--- a/src/intervals.h
+++ b/src/intervals.h
@@ -64,71 +64,71 @@ struct interval
64 Lisp_Object plist; 64 Lisp_Object plist;
65}; 65};
66 66
67/* These are macros for dealing with the interval tree. */ 67/* These are macros for dealing with the interval tree. */
68 68
69/* Size of the structure used to represent an interval */ 69/* Size of the structure used to represent an interval. */
70#define INTERVAL_SIZE (sizeof (struct interval)) 70#define INTERVAL_SIZE (sizeof (struct interval))
71 71
72/* Size of a pointer to an interval structure */ 72/* Size of a pointer to an interval structure. */
73#define INTERVAL_PTR_SIZE (sizeof (struct interval *)) 73#define INTERVAL_PTR_SIZE (sizeof (struct interval *))
74 74
75#define NULL_INTERVAL_P(i) ((i) == NULL_INTERVAL) 75#define NULL_INTERVAL_P(i) ((i) == NULL_INTERVAL)
76 76
77/* True if this interval has no right child. */ 77/* True if this interval has no right child. */
78#define NULL_RIGHT_CHILD(i) ((i)->right == NULL_INTERVAL) 78#define NULL_RIGHT_CHILD(i) ((i)->right == NULL_INTERVAL)
79 79
80/* True if this interval has no left child. */ 80/* True if this interval has no left child. */
81#define NULL_LEFT_CHILD(i) ((i)->left == NULL_INTERVAL) 81#define NULL_LEFT_CHILD(i) ((i)->left == NULL_INTERVAL)
82 82
83/* True if this interval has no parent. */ 83/* True if this interval has no parent. */
84#define NULL_PARENT(i) ((i)->up_obj || (i)->up.interval == 0) 84#define NULL_PARENT(i) ((i)->up_obj || (i)->up.interval == 0)
85 85
86/* True if this interval is the left child of some other interval. */ 86/* True if this interval is the left child of some other interval. */
87#define AM_LEFT_CHILD(i) (! NULL_PARENT (i) \ 87#define AM_LEFT_CHILD(i) (! NULL_PARENT (i) \
88 && INTERVAL_PARENT (i)->left == (i)) 88 && INTERVAL_PARENT (i)->left == (i))
89 89
90/* True if this interval is the right child of some other interval. */ 90/* True if this interval is the right child of some other interval. */
91#define AM_RIGHT_CHILD(i) (! NULL_PARENT (i) \ 91#define AM_RIGHT_CHILD(i) (! NULL_PARENT (i) \
92 && INTERVAL_PARENT (i)->right == (i)) 92 && INTERVAL_PARENT (i)->right == (i))
93 93
94/* True if this interval has no children. */ 94/* True if this interval has no children. */
95#define LEAF_INTERVAL_P(i) ((i)->left == NULL_INTERVAL \ 95#define LEAF_INTERVAL_P(i) ((i)->left == NULL_INTERVAL \
96 && (i)->right == NULL_INTERVAL) 96 && (i)->right == NULL_INTERVAL)
97 97
98/* True if this interval has no parent and is therefore the root. */ 98/* True if this interval has no parent and is therefore the root. */
99#define ROOT_INTERVAL_P(i) (NULL_PARENT (i)) 99#define ROOT_INTERVAL_P(i) (NULL_PARENT (i))
100 100
101/* True if this interval is the only interval in the interval tree. */ 101/* True if this interval is the only interval in the interval tree. */
102#define ONLY_INTERVAL_P(i) (ROOT_INTERVAL_P ((i)) && LEAF_INTERVAL_P ((i))) 102#define ONLY_INTERVAL_P(i) (ROOT_INTERVAL_P ((i)) && LEAF_INTERVAL_P ((i)))
103 103
104/* True if this interval has both left and right children. */ 104/* True if this interval has both left and right children. */
105#define BOTH_KIDS_P(i) ((i)->left != NULL_INTERVAL \ 105#define BOTH_KIDS_P(i) ((i)->left != NULL_INTERVAL \
106 && (i)->right != NULL_INTERVAL) 106 && (i)->right != NULL_INTERVAL)
107 107
108/* The total size of all text represented by this interval and all its 108/* The total size of all text represented by this interval and all its
109 children in the tree. This is zero if the interval is null. */ 109 children in the tree. This is zero if the interval is null. */
110#define TOTAL_LENGTH(i) ((i) == NULL_INTERVAL ? 0 : (i)->total_length) 110#define TOTAL_LENGTH(i) ((i) == NULL_INTERVAL ? 0 : (i)->total_length)
111 111
112/* The size of text represented by this interval alone. */ 112/* The size of text represented by this interval alone. */
113#define LENGTH(i) ((i) == NULL_INTERVAL ? 0 : (TOTAL_LENGTH ((i)) \ 113#define LENGTH(i) ((i) == NULL_INTERVAL ? 0 : (TOTAL_LENGTH ((i)) \
114 - TOTAL_LENGTH ((i)->right) \ 114 - TOTAL_LENGTH ((i)->right) \
115 - TOTAL_LENGTH ((i)->left))) 115 - TOTAL_LENGTH ((i)->left)))
116 116
117/* The position of the character just past the end of I. Note that 117/* The position of the character just past the end of I. Note that
118 the position cache i->position must be valid for this to work. */ 118 the position cache i->position must be valid for this to work. */
119#define INTERVAL_LAST_POS(i) ((i)->position + LENGTH ((i))) 119#define INTERVAL_LAST_POS(i) ((i)->position + LENGTH ((i)))
120 120
121/* The total size of the left subtree of this interval. */ 121/* The total size of the left subtree of this interval. */
122#define LEFT_TOTAL_LENGTH(i) ((i)->left ? (i)->left->total_length : 0) 122#define LEFT_TOTAL_LENGTH(i) ((i)->left ? (i)->left->total_length : 0)
123 123
124/* The total size of the right subtree of this interval. */ 124/* The total size of the right subtree of this interval. */
125#define RIGHT_TOTAL_LENGTH(i) ((i)->right ? (i)->right->total_length : 0) 125#define RIGHT_TOTAL_LENGTH(i) ((i)->right ? (i)->right->total_length : 0)
126 126
127 127
128/* These macros are for dealing with the interval properties. */ 128/* These macros are for dealing with the interval properties. */
129 129
130/* True if this is a default interval, which is the same as being null 130/* True if this is a default interval, which is the same as being null
131 or having no properties. */ 131 or having no properties. */
132#define DEFAULT_INTERVAL_P(i) (NULL_INTERVAL_P (i) || EQ ((i)->plist, Qnil)) 132#define DEFAULT_INTERVAL_P(i) (NULL_INTERVAL_P (i) || EQ ((i)->plist, Qnil))
133 133
134/* Test what type of parent we have. Three possibilities: another 134/* Test what type of parent we have. Three possibilities: another
@@ -169,7 +169,7 @@ struct interval
169 } \ 169 } \
170 while (0) 170 while (0)
171 171
172/* Reset this interval to its vanilla, or no-property state. */ 172/* Reset this interval to its vanilla, or no-property state. */
173#define RESET_INTERVAL(i) \ 173#define RESET_INTERVAL(i) \
174{ \ 174{ \
175 (i)->total_length = (i)->position = 0; \ 175 (i)->total_length = (i)->position = 0; \
@@ -181,7 +181,7 @@ struct interval
181 (i)->plist = Qnil; \ 181 (i)->plist = Qnil; \
182} 182}
183 183
184/* Copy the cached property values of interval FROM to interval TO. */ 184/* Copy the cached property values of interval FROM to interval TO. */
185#define COPY_INTERVAL_CACHE(from,to) \ 185#define COPY_INTERVAL_CACHE(from,to) \
186{ \ 186{ \
187 (to)->write_protect = (from)->write_protect; \ 187 (to)->write_protect = (from)->write_protect; \
@@ -190,7 +190,7 @@ struct interval
190 (to)->rear_sticky = (from)->rear_sticky; \ 190 (to)->rear_sticky = (from)->rear_sticky; \
191} 191}
192 192
193/* Copy only the set bits of FROM's cache. */ 193/* Copy only the set bits of FROM's cache. */
194#define MERGE_INTERVAL_CACHE(from,to) \ 194#define MERGE_INTERVAL_CACHE(from,to) \
195{ \ 195{ \
196 if ((from)->write_protect) (to)->write_protect = 1; \ 196 if ((from)->write_protect) (to)->write_protect = 1; \
@@ -201,18 +201,18 @@ struct interval
201 201
202/* Macro determining whether the properties of an interval being 202/* Macro determining whether the properties of an interval being
203 inserted should be merged with the properties of the text where 203 inserted should be merged with the properties of the text where
204 they are being inserted. */ 204 they are being inserted. */
205#define MERGE_INSERTIONS(i) 1 205#define MERGE_INSERTIONS(i) 1
206 206
207/* Macro determining if an invisible interval should be displayed 207/* Macro determining if an invisible interval should be displayed
208 as a special glyph, or not at all. */ 208 as a special glyph, or not at all. */
209#define DISPLAY_INVISIBLE_GLYPH(i) 0 209#define DISPLAY_INVISIBLE_GLYPH(i) 0
210 210
211/* Is this interval visible? Replace later with cache access */ 211/* Is this interval visible? Replace later with cache access. */
212#define INTERVAL_VISIBLE_P(i) \ 212#define INTERVAL_VISIBLE_P(i) \
213 (! NULL_INTERVAL_P (i) && NILP (textget ((i)->plist, Qinvisible))) 213 (! NULL_INTERVAL_P (i) && NILP (textget ((i)->plist, Qinvisible)))
214 214
215/* Is this interval writable? Replace later with cache access */ 215/* Is this interval writable? Replace later with cache access. */
216#define INTERVAL_WRITABLE_P(i) \ 216#define INTERVAL_WRITABLE_P(i) \
217 (! NULL_INTERVAL_P (i) \ 217 (! NULL_INTERVAL_P (i) \
218 && (NILP (textget ((i)->plist, Qread_only)) \ 218 && (NILP (textget ((i)->plist, Qread_only)) \
@@ -222,7 +222,7 @@ struct interval
222 : !NILP (Vinhibit_read_only))))) \ 222 : !NILP (Vinhibit_read_only))))) \
223 223
224/* Macros to tell whether insertions before or after this interval 224/* Macros to tell whether insertions before or after this interval
225 should stick to it. */ 225 should stick to it. */
226/* Replace later with cache access */ 226/* Replace later with cache access */
227/*#define FRONT_STICKY_P(i) ((i)->front_sticky != 0) 227/*#define FRONT_STICKY_P(i) ((i)->front_sticky != 0)
228 #define END_STICKY_P(i) ((i)->rear_sticky != 0)*/ 228 #define END_STICKY_P(i) ((i)->rear_sticky != 0)*/
@@ -245,11 +245,11 @@ struct interval
245 ? !NILP (prop) \ 245 ? !NILP (prop) \
246 : invisible_p (prop, BVAR (current_buffer, invisibility_spec))) 246 : invisible_p (prop, BVAR (current_buffer, invisibility_spec)))
247 247
248/* Declared in alloc.c */ 248/* Declared in alloc.c. */
249 249
250extern INTERVAL make_interval (void); 250extern INTERVAL make_interval (void);
251 251
252/* Declared in intervals.c */ 252/* Declared in intervals.c. */
253 253
254extern INTERVAL create_root_interval (Lisp_Object); 254extern INTERVAL create_root_interval (Lisp_Object);
255extern void copy_properties (INTERVAL, INTERVAL); 255extern void copy_properties (INTERVAL, INTERVAL);
@@ -288,12 +288,12 @@ extern INTERVAL validate_interval_range (Lisp_Object, Lisp_Object *,
288 Lisp_Object *, int); 288 Lisp_Object *, int);
289extern INTERVAL interval_of (EMACS_INT, Lisp_Object); 289extern INTERVAL interval_of (EMACS_INT, Lisp_Object);
290 290
291/* Defined in xdisp.c */ 291/* Defined in xdisp.c. */
292extern int invisible_p (Lisp_Object, Lisp_Object); 292extern int invisible_p (Lisp_Object, Lisp_Object);
293 293
294/* Declared in textprop.c */ 294/* Declared in textprop.c. */
295 295
296/* Types of hooks. */ 296/* Types of hooks. */
297extern Lisp_Object Qpoint_left; 297extern Lisp_Object Qpoint_left;
298extern Lisp_Object Qpoint_entered; 298extern Lisp_Object Qpoint_entered;
299extern Lisp_Object Qmodification_hooks; 299extern Lisp_Object Qmodification_hooks;
@@ -301,11 +301,11 @@ extern Lisp_Object Qcategory;
301extern Lisp_Object Qlocal_map; 301extern Lisp_Object Qlocal_map;
302extern Lisp_Object Qkeymap; 302extern Lisp_Object Qkeymap;
303 303
304/* Visual properties text (including strings) may have. */ 304/* Visual properties text (including strings) may have. */
305extern Lisp_Object Qfont; 305extern Lisp_Object Qfont;
306extern Lisp_Object Qinvisible, Qintangible; 306extern Lisp_Object Qinvisible, Qintangible;
307 307
308/* Sticky properties */ 308/* Sticky properties. */
309extern Lisp_Object Qfront_sticky, Qrear_nonsticky; 309extern Lisp_Object Qfront_sticky, Qrear_nonsticky;
310 310
311EXFUN (Fget_char_property, 3); 311EXFUN (Fget_char_property, 3);