rmail-output-read-file-name fix for bug#12214
[bpt/emacs.git] / src / intervals.h
CommitLineData
90ba40fc 1/* Definitions and global variables for intervals.
acaf905b 2 Copyright (C) 1993-1994, 2000-2012 Free Software Foundation, Inc.
90ba40fc
JA
3
4This file is part of GNU Emacs.
5
b9b1cc14 6GNU Emacs is free software: you can redistribute it and/or modify
90ba40fc 7it under the terms of the GNU General Public License as published by
b9b1cc14
GM
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
90ba40fc
JA
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
b9b1cc14 17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
90ba40fc 18
90ba40fc
JA
19#include "dispextern.h"
20
6a3d20cc 21INLINE_HEADER_BEGIN
42b3a444
DA
22#ifndef INTERVALS_INLINE
23# define INTERVALS_INLINE INLINE
24#endif
6a3d20cc 25
4a6a76d9
SM
26/* Basic data type for use of intervals. */
27
28struct interval
29{
30 /* The first group of entries deal with the tree structure. */
31
d311d28c
PE
32 ptrdiff_t total_length; /* Length of myself and both children. */
33 ptrdiff_t position; /* Cache of interval's character position. */
4a6a76d9
SM
34 /* This field is usually updated
35 simultaneously with an interval
36 traversal, there is no guarantee
37 that it is valid for a random
38 interval. */
39 struct interval *left; /* Intervals which precede me. */
40 struct interval *right; /* Intervals which succeed me. */
41
42 /* Parent in the tree, or the Lisp_Object containing this interval tree. */
43 union
44 {
45 struct interval *interval;
46 Lisp_Object obj;
47 } up;
48 unsigned int up_obj : 1;
49
50 unsigned gcmarkbit : 1;
51
52 /* The remaining components are `properties' of the interval.
53 The first four are duplicates for things which can be on the list,
54 for purposes of speed. */
55
56 unsigned int write_protect : 1; /* Non-zero means can't modify. */
57 unsigned int visible : 1; /* Zero means don't display. */
58 unsigned int front_sticky : 1; /* Non-zero means text inserted just
59 before this interval goes into it. */
60 unsigned int rear_sticky : 1; /* Likewise for just after it. */
cce7fefc 61 Lisp_Object plist; /* Other properties. */
4a6a76d9
SM
62};
63
b50a28de 64/* These are macros for dealing with the interval tree. */
90ba40fc 65
b50a28de 66/* True if this interval has no right child. */
77c7bcb1 67#define NULL_RIGHT_CHILD(i) ((i)->right == NULL)
90ba40fc 68
b50a28de 69/* True if this interval has no left child. */
77c7bcb1 70#define NULL_LEFT_CHILD(i) ((i)->left == NULL)
90ba40fc 71
b50a28de 72/* True if this interval has no parent. */
e0b8c689 73#define NULL_PARENT(i) ((i)->up_obj || (i)->up.interval == 0)
90ba40fc 74
b50a28de 75/* True if this interval is the left child of some other interval. */
77c7bcb1
DA
76#define AM_LEFT_CHILD(i) \
77 (! NULL_PARENT (i) && INTERVAL_PARENT (i)->left == (i))
90ba40fc 78
b50a28de 79/* True if this interval is the right child of some other interval. */
77c7bcb1
DA
80#define AM_RIGHT_CHILD(i) \
81 (! NULL_PARENT (i) && INTERVAL_PARENT (i)->right == (i))
90ba40fc 82
b50a28de 83/* True if this interval has no children. */
77c7bcb1 84#define LEAF_INTERVAL_P(i) ((i)->left == NULL && (i)->right == NULL)
90ba40fc 85
b50a28de 86/* True if this interval has no parent and is therefore the root. */
90ba40fc
JA
87#define ROOT_INTERVAL_P(i) (NULL_PARENT (i))
88
b50a28de 89/* True if this interval is the only interval in the interval tree. */
7ac78c9a 90#define ONLY_INTERVAL_P(i) (ROOT_INTERVAL_P ((i)) && LEAF_INTERVAL_P ((i)))
90ba40fc 91
b50a28de 92/* True if this interval has both left and right children. */
77c7bcb1 93#define BOTH_KIDS_P(i) ((i)->left != NULL && (i)->right != NULL)
90ba40fc
JA
94
95/* The total size of all text represented by this interval and all its
b50a28de 96 children in the tree. This is zero if the interval is null. */
77c7bcb1 97#define TOTAL_LENGTH(i) ((i) == NULL ? 0 : (i)->total_length)
90ba40fc 98
b50a28de 99/* The size of text represented by this interval alone. */
77c7bcb1
DA
100#define LENGTH(i) ((i) == NULL ? 0 : (TOTAL_LENGTH ((i)) \
101 - TOTAL_LENGTH ((i)->right) \
102 - TOTAL_LENGTH ((i)->left)))
90ba40fc 103
3fc86d4b 104/* The position of the character just past the end of I. Note that
b50a28de 105 the position cache i->position must be valid for this to work. */
3fc86d4b 106#define INTERVAL_LAST_POS(i) ((i)->position + LENGTH ((i)))
90ba40fc 107
b50a28de 108/* The total size of the left subtree of this interval. */
90ba40fc
JA
109#define LEFT_TOTAL_LENGTH(i) ((i)->left ? (i)->left->total_length : 0)
110
b50a28de 111/* The total size of the right subtree of this interval. */
90ba40fc
JA
112#define RIGHT_TOTAL_LENGTH(i) ((i)->right ? (i)->right->total_length : 0)
113
b50a28de 114/* These macros are for dealing with the interval properties. */
90ba40fc
JA
115
116/* True if this is a default interval, which is the same as being null
b50a28de 117 or having no properties. */
77c7bcb1 118#define DEFAULT_INTERVAL_P(i) (!i || EQ ((i)->plist, Qnil))
90ba40fc 119
439d5cb4 120/* Test what type of parent we have. Three possibilities: another
77c7bcb1 121 interval, a buffer or string object, or NULL. */
e0b8c689
KR
122#define INTERVAL_HAS_PARENT(i) ((i)->up_obj == 0 && (i)->up.interval != 0)
123#define INTERVAL_HAS_OBJECT(i) ((i)->up_obj)
439d5cb4 124
6a3d20cc 125/* Use these macros to get parent of an interval.
439d5cb4
KR
126
127 The choice of macros is dependent on the type needed. Don't add
128 casts to get around this, it will break some development work in
129 progress. */
6a3d20cc
DA
130
131#define INTERVAL_PARENT(i) \
132 (eassert ((i) != 0 && (i)->up_obj == 0), (i)->up.interval)
133
134#define GET_INTERVAL_OBJECT(d,s) (eassert ((s)->up_obj == 1), (d) = (s)->up.obj)
135
136/* Use these functions to set Lisp_Object
137 or pointer slots of struct interval. */
138
42b3a444 139INTERVALS_INLINE void
6a3d20cc
DA
140interval_set_parent (INTERVAL i, INTERVAL parent)
141{
142 i->up_obj = 0;
143 i->up.interval = parent;
144}
145
42b3a444 146INTERVALS_INLINE void
6a3d20cc
DA
147interval_set_object (INTERVAL i, Lisp_Object obj)
148{
149 eassert (BUFFERP (obj) || STRINGP (obj));
150 i->up_obj = 1;
151 i->up.obj = obj;
152}
153
42b3a444 154INTERVALS_INLINE void
6a3d20cc
DA
155interval_set_left (INTERVAL i, INTERVAL left)
156{
157 i->left = left;
158}
159
42b3a444 160INTERVALS_INLINE void
6a3d20cc
DA
161interval_set_right (INTERVAL i, INTERVAL right)
162{
163 i->right = right;
164}
165
42b3a444 166INTERVALS_INLINE Lisp_Object
6a3d20cc
DA
167interval_set_plist (INTERVAL i, Lisp_Object plist)
168{
169 i->plist = plist;
170 return plist;
171}
172
173/* Make the parent of D be whatever the parent of S is, regardless
174 of the type. This is used when balancing an interval tree. */
175
42b3a444 176INTERVALS_INLINE void
6a3d20cc
DA
177interval_copy_parent (INTERVAL d, INTERVAL s)
178{
179 d->up = s->up;
180 d->up_obj = s->up_obj;
181}
439d5cb4
KR
182
183/* Get the parent interval, if any, otherwise a null pointer. Useful
184 for walking up to the root in a "for" loop; use this to get the
77c7bcb1 185 "next" value, and test the result to see if it's NULL. */
4a6a76d9
SM
186#define INTERVAL_PARENT_OR_NULL(i) \
187 (INTERVAL_HAS_PARENT (i) ? INTERVAL_PARENT (i) : 0)
439d5cb4 188
b50a28de 189/* Reset this interval to its vanilla, or no-property state. */
6a3d20cc
DA
190#define RESET_INTERVAL(i) \
191{ \
192 (i)->total_length = (i)->position = 0; \
77c7bcb1
DA
193 (i)->left = (i)->right = NULL; \
194 interval_set_parent (i, NULL); \
6a3d20cc
DA
195 (i)->write_protect = 0; \
196 (i)->visible = 0; \
197 (i)->front_sticky = (i)->rear_sticky = 0; \
198 interval_set_plist (i, Qnil); \
7ac78c9a 199}
90ba40fc 200
b50a28de 201/* Copy the cached property values of interval FROM to interval TO. */
6a3d20cc
DA
202#define COPY_INTERVAL_CACHE(from,to) \
203{ \
204 (to)->write_protect = (from)->write_protect; \
205 (to)->visible = (from)->visible; \
206 (to)->front_sticky = (from)->front_sticky; \
207 (to)->rear_sticky = (from)->rear_sticky; \
90ba40fc
JA
208}
209
b50a28de 210/* Copy only the set bits of FROM's cache. */
6a3d20cc
DA
211#define MERGE_INTERVAL_CACHE(from,to) \
212{ \
90ba40fc 213 if ((from)->write_protect) (to)->write_protect = 1; \
6a3d20cc 214 if ((from)->visible) (to)->visible = 1; \
90ba40fc
JA
215 if ((from)->front_sticky) (to)->front_sticky = 1; \
216 if ((from)->rear_sticky) (to)->rear_sticky = 1; \
217}
218
b50a28de 219/* Is this interval visible? Replace later with cache access. */
90ba40fc 220#define INTERVAL_VISIBLE_P(i) \
77c7bcb1 221 (i && NILP (textget ((i)->plist, Qinvisible)))
90ba40fc 222
b50a28de 223/* Is this interval writable? Replace later with cache access. */
5f8a398a 224#define INTERVAL_WRITABLE_P(i) \
77c7bcb1
DA
225 (i && (NILP (textget ((i)->plist, Qread_only)) \
226 || ((CONSP (Vinhibit_read_only) \
227 ? !NILP (Fmemq (textget ((i)->plist, Qread_only), \
228 Vinhibit_read_only)) \
229 : !NILP (Vinhibit_read_only))))) \
90ba40fc
JA
230
231/* Macros to tell whether insertions before or after this interval
77c7bcb1
DA
232 should stick to it. Now we have Vtext_property_default_nonsticky,
233 so these macros are unreliable now and never used. */
234
235#if 0
236#define FRONT_STICKY_P(i) \
237 (i && ! NILP (textget ((i)->plist, Qfront_sticky)))
238#define END_NONSTICKY_P(i) \
239 (i && ! NILP (textget ((i)->plist, Qrear_nonsticky)))
240#define FRONT_NONSTICKY_P(i) \
241 (i && ! EQ (Qt, textget ((i)->plist, Qfront_sticky)))
242#endif
90ba40fc 243
47b4c04d 244/* If PROP is the `invisible' property of a character,
99776d43
SM
245 this is 1 if the character should be treated as invisible,
246 and 2 if it is invisible but with an ellipsis. */
47b4c04d 247
77c7bcb1 248#define TEXT_PROP_MEANS_INVISIBLE(prop) \
4b4deea2 249 (EQ (BVAR (current_buffer, invisibility_spec), Qt) \
77c7bcb1 250 ? !NILP (prop) \
4b4deea2 251 : invisible_p (prop, BVAR (current_buffer, invisibility_spec)))
47b4c04d 252
b50a28de 253/* Declared in alloc.c. */
90ba40fc 254
383e0970 255extern INTERVAL make_interval (void);
90ba40fc 256
b50a28de 257/* Declared in intervals.c. */
90ba40fc 258
383e0970
J
259extern INTERVAL create_root_interval (Lisp_Object);
260extern void copy_properties (INTERVAL, INTERVAL);
261extern int intervals_equal (INTERVAL, INTERVAL);
d311d28c 262extern void traverse_intervals (INTERVAL, ptrdiff_t,
383e0970
J
263 void (*) (INTERVAL, Lisp_Object),
264 Lisp_Object);
265extern void traverse_intervals_noorder (INTERVAL,
266 void (*) (INTERVAL, Lisp_Object),
267 Lisp_Object);
d311d28c
PE
268extern INTERVAL split_interval_right (INTERVAL, ptrdiff_t);
269extern INTERVAL split_interval_left (INTERVAL, ptrdiff_t);
270extern INTERVAL find_interval (INTERVAL, ptrdiff_t);
383e0970
J
271extern INTERVAL next_interval (INTERVAL);
272extern INTERVAL previous_interval (INTERVAL);
273extern INTERVAL merge_interval_left (INTERVAL);
d311d28c
PE
274extern void offset_intervals (struct buffer *, ptrdiff_t, ptrdiff_t);
275extern void graft_intervals_into_buffer (INTERVAL, ptrdiff_t, ptrdiff_t,
383e0970 276 struct buffer *, int);
d1dfb56c 277extern void verify_interval_modification (struct buffer *,
d311d28c 278 ptrdiff_t, ptrdiff_t);
383e0970 279extern INTERVAL balance_intervals (INTERVAL);
b7982059 280extern void copy_intervals_to_string (Lisp_Object, struct buffer *,
d311d28c
PE
281 ptrdiff_t, ptrdiff_t);
282extern INTERVAL copy_intervals (INTERVAL, ptrdiff_t, ptrdiff_t);
383e0970
J
283extern int compare_string_intervals (Lisp_Object, Lisp_Object);
284extern Lisp_Object textget (Lisp_Object, Lisp_Object);
285extern Lisp_Object lookup_char_property (Lisp_Object, Lisp_Object, int);
d311d28c
PE
286extern void move_if_not_intangible (ptrdiff_t);
287extern int get_property_and_range (ptrdiff_t, Lisp_Object, Lisp_Object *,
288 ptrdiff_t *, ptrdiff_t *, Lisp_Object);
289extern Lisp_Object get_local_map (ptrdiff_t, struct buffer *, Lisp_Object);
290extern INTERVAL update_interval (INTERVAL, ptrdiff_t);
383e0970
J
291extern void set_intervals_multibyte (int);
292extern INTERVAL validate_interval_range (Lisp_Object, Lisp_Object *,
293 Lisp_Object *, int);
d311d28c 294extern INTERVAL interval_of (ptrdiff_t, Lisp_Object);
d748a3db 295
b50a28de 296/* Defined in xdisp.c. */
383e0970 297extern int invisible_p (Lisp_Object, Lisp_Object);
90ba40fc 298
b50a28de 299/* Declared in textprop.c. */
90ba40fc 300
b50a28de 301/* Types of hooks. */
90ba40fc
JA
302extern Lisp_Object Qpoint_left;
303extern Lisp_Object Qpoint_entered;
1a7c673b
RS
304extern Lisp_Object Qmodification_hooks;
305extern Lisp_Object Qcategory;
306extern Lisp_Object Qlocal_map;
b4030d7b 307extern Lisp_Object Qkeymap;
90ba40fc 308
b50a28de 309/* Visual properties text (including strings) may have. */
955cbe7b
PE
310extern Lisp_Object Qfont;
311extern Lisp_Object Qinvisible, Qintangible;
90ba40fc 312
b50a28de 313/* Sticky properties. */
58943db0
RS
314extern Lisp_Object Qfront_sticky, Qrear_nonsticky;
315
383e0970
J
316extern Lisp_Object copy_text_properties (Lisp_Object, Lisp_Object,
317 Lisp_Object, Lisp_Object,
318 Lisp_Object, Lisp_Object);
319extern Lisp_Object set_text_properties (Lisp_Object, Lisp_Object,
320 Lisp_Object, Lisp_Object,
321 Lisp_Object);
322extern void set_text_properties_1 (Lisp_Object, Lisp_Object,
323 Lisp_Object, Lisp_Object, INTERVAL);
324
325Lisp_Object text_property_list (Lisp_Object, Lisp_Object, Lisp_Object,
326 Lisp_Object);
327int add_text_properties_from_list (Lisp_Object, Lisp_Object, Lisp_Object);
328Lisp_Object extend_property_ranges (Lisp_Object, Lisp_Object);
329Lisp_Object get_char_property_and_overlay (Lisp_Object, Lisp_Object,
330 Lisp_Object, Lisp_Object*);
331extern int text_property_stickiness (Lisp_Object prop, Lisp_Object pos,
332 Lisp_Object buffer);
333extern Lisp_Object get_pos_property (Lisp_Object pos, Lisp_Object prop,
334 Lisp_Object object);
335
336extern void syms_of_textprop (void);
a5ecc8a3
KH
337
338#include "composite.h"
6a3d20cc
DA
339
340INLINE_HEADER_END