root/src/intervals.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. set_interval_object
  2. set_interval_parent
  3. set_interval_plist

     1 /* Definitions and global variables for intervals.
     2    Copyright (C) 1993-1994, 2000-2023 Free Software Foundation, Inc.
     3 
     4 This file is part of GNU Emacs.
     5 
     6 GNU Emacs is free software: you can redistribute it and/or modify
     7 it under the terms of the GNU General Public License as published by
     8 the Free Software Foundation, either version 3 of the License, or (at
     9 your option) any later version.
    10 
    11 GNU Emacs is distributed in the hope that it will be useful,
    12 but WITHOUT ANY WARRANTY; without even the implied warranty of
    13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14 GNU General Public License for more details.
    15 
    16 You should have received a copy of the GNU General Public License
    17 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    18 
    19 #ifndef EMACS_INTERVALS_H
    20 #define EMACS_INTERVALS_H
    21 
    22 #include "buffer.h"
    23 #include "lisp.h"
    24 
    25 INLINE_HEADER_BEGIN
    26 
    27 /* Basic data type for use of intervals.  */
    28 
    29 struct interval
    30 {
    31   /* The first group of entries deal with the tree structure.  */
    32   ptrdiff_t total_length;       /* Length of myself and both children.  */
    33   ptrdiff_t position;           /* Cache of interval's character position.  */
    34                                 /* This field is valid in the final
    35                                    target interval returned by
    36                                    find_interval, next_interval,
    37                                    previous_interval and
    38                                    update_interval.  It cannot be
    39                                    depended upon in any intermediate
    40                                    intervals traversed by these
    41                                    functions, or any other
    42                                    interval. */
    43   struct interval *left;        /* Intervals which precede me.  */
    44   struct interval *right;       /* Intervals which succeed me.  */
    45 
    46   /* Parent in the tree, or the Lisp_Object containing this interval tree.  */
    47   union
    48   {
    49     struct interval *interval;
    50     Lisp_Object obj;
    51   } up;
    52   bool_bf up_obj : 1;
    53 
    54   bool_bf gcmarkbit : 1;
    55 
    56   /* The remaining components are `properties' of the interval.
    57      The first four are duplicates for things which can be on the list,
    58      for purposes of speed.  */
    59 
    60   bool_bf write_protect : 1;        /* True means can't modify.  */
    61   bool_bf visible : 1;              /* False means don't display.  */
    62   bool_bf front_sticky : 1;         /* True means text inserted just
    63                                        before this interval goes into it.  */
    64   bool_bf rear_sticky : 1;          /* Likewise for just after it.  */
    65   Lisp_Object plist;                /* Other properties.  */
    66 };
    67 
    68 /* These are macros for dealing with the interval tree.  */
    69 
    70 /* True if this interval has no right child.  */
    71 #define NULL_RIGHT_CHILD(i) ((i)->right == NULL)
    72 
    73 /* True if this interval has no left child.  */
    74 #define NULL_LEFT_CHILD(i) ((i)->left == NULL)
    75 
    76 /* True if this interval has no parent.  */
    77 #define NULL_PARENT(i) ((i)->up_obj || (i)->up.interval == 0)
    78 
    79 /* True if this interval is the left child of some other interval.  */
    80 #define AM_LEFT_CHILD(i)                                        \
    81   (! NULL_PARENT (i) && INTERVAL_PARENT (i)->left == (i))
    82 
    83 /* True if this interval is the right child of some other interval.  */
    84 #define AM_RIGHT_CHILD(i)                                       \
    85   (! NULL_PARENT (i) && INTERVAL_PARENT (i)->right == (i))
    86 
    87 /* True if this interval has no children.  */
    88 #define LEAF_INTERVAL_P(i) ((i)->left == NULL && (i)->right == NULL)
    89 
    90 /* True if this interval has no parent and is therefore the root.  */
    91 #define ROOT_INTERVAL_P(i) NULL_PARENT (i)
    92 
    93 /* True if this interval is the only interval in the interval tree.  */
    94 #define ONLY_INTERVAL_P(i) (ROOT_INTERVAL_P (i) && LEAF_INTERVAL_P (i))
    95 
    96 /* True if this interval has both left and right children.  */
    97 #define BOTH_KIDS_P(i) ((i)->left != NULL && (i)->right != NULL)
    98 
    99 /* The total size of all text represented by the nonnull interval I
   100    and all its children in the tree.  */
   101 #define TOTAL_LENGTH(i) ((i)->total_length)
   102 
   103 /* Likewise, but also defined to be zero if I is null.  */
   104 #define TOTAL_LENGTH0(i) ((i) ? TOTAL_LENGTH (i) : 0)
   105 
   106 /* The size of text represented by this interval alone.  */
   107 #define LENGTH(i) (TOTAL_LENGTH (i)             \
   108                    - RIGHT_TOTAL_LENGTH (i)     \
   109                    - LEFT_TOTAL_LENGTH (i))
   110 
   111 /* The position of the character just past the end of I.  Note that
   112    the position cache i->position must be valid for this to work.  */
   113 #define INTERVAL_LAST_POS(i) ((i)->position + LENGTH (i))
   114 
   115 /* The total size of the left subtree of this interval.  */
   116 #define LEFT_TOTAL_LENGTH(i) TOTAL_LENGTH0 ((i)->left)
   117 
   118 /* The total size of the right subtree of this interval.  */
   119 #define RIGHT_TOTAL_LENGTH(i) TOTAL_LENGTH0 ((i)->right)
   120 
   121 /* These macros are for dealing with the interval properties.  */
   122 
   123 /* True if this is a default interval, which is the same as being null
   124    or having no properties.  */
   125 #define DEFAULT_INTERVAL_P(i) (!i || NILP ((i)->plist))
   126 
   127 /* Test what type of parent we have.  Three possibilities: another
   128    interval, a buffer or string object, or NULL.  */
   129 #define INTERVAL_HAS_PARENT(i) (! (i)->up_obj && (i)->up.interval != 0)
   130 #define INTERVAL_HAS_OBJECT(i) ((i)->up_obj)
   131 
   132 /* Use these macros to get parent of an interval.
   133 
   134    The choice of macros is dependent on the type needed.  Don't add
   135    casts to get around this, it will break some development work in
   136    progress.  */
   137 
   138 #define INTERVAL_PARENT(i)                                      \
   139    (eassert ((i) != 0 && ! (i)->up_obj), (i)->up.interval)
   140 
   141 #define GET_INTERVAL_OBJECT(d,s) (eassert ((s)->up_obj), (d) = (s)->up.obj)
   142 
   143 /* Use these functions to set Lisp_Object
   144    or pointer slots of struct interval.  */
   145 
   146 INLINE void
   147 set_interval_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 
   154 INLINE void
   155 set_interval_parent (INTERVAL i, INTERVAL parent)
   156 {
   157   i->up_obj = false;
   158   i->up.interval = parent;
   159 }
   160 
   161 INLINE void
   162 set_interval_plist (INTERVAL i, Lisp_Object plist)
   163 {
   164   i->plist = plist;
   165 }
   166 
   167 /* Get the parent interval, if any, otherwise a null pointer.  Useful
   168    for walking up to the root in a "for" loop; use this to get the
   169    "next" value, and test the result to see if it's NULL.  */
   170 #define INTERVAL_PARENT_OR_NULL(i) \
   171    (INTERVAL_HAS_PARENT (i) ? INTERVAL_PARENT (i) : 0)
   172 
   173 /* Reset this interval to its vanilla, or no-property state.  */
   174 #define RESET_INTERVAL(i)                     \
   175  do {                                         \
   176   (i)->total_length = (i)->position = 0;      \
   177   (i)->left = (i)->right = NULL;              \
   178   set_interval_parent (i, NULL);              \
   179   (i)->write_protect = false;                 \
   180   (i)->visible = false;                       \
   181   (i)->front_sticky = (i)->rear_sticky = false; \
   182   set_interval_plist (i, Qnil);               \
   183  } while (false)
   184 
   185 /* Copy the cached property values of interval FROM to interval TO.  */
   186 #define COPY_INTERVAL_CACHE(from,to)            \
   187  do {                                           \
   188   (to)->write_protect = (from)->write_protect;  \
   189   (to)->visible = (from)->visible;              \
   190   (to)->front_sticky = (from)->front_sticky;    \
   191   (to)->rear_sticky = (from)->rear_sticky;      \
   192  } while (false)
   193 
   194 /* Copy only the set bits of FROM's cache.  */
   195 #define MERGE_INTERVAL_CACHE(from,to)                           \
   196  do {                                                           \
   197   if ((from)->write_protect) (to)->write_protect = true;        \
   198   if ((from)->visible) (to)->visible = true;                    \
   199   if ((from)->front_sticky) (to)->front_sticky = true;          \
   200   if ((from)->rear_sticky) (to)->rear_sticky = true;            \
   201  } while (false)
   202 
   203 /* Is this interval visible?  Replace later with cache access.  */
   204 #define INTERVAL_VISIBLE_P(i) \
   205   (i && NILP (textget ((i)->plist, Qinvisible)))
   206 
   207 /* Is this interval writable?  Replace later with cache access.  */
   208 #define INTERVAL_WRITABLE_P(i)                                  \
   209   (NILP (textget ((i)->plist, Qread_only))                      \
   210    || !NILP (textget ((i)->plist, Qinhibit_read_only))          \
   211    || ((CONSP (Vinhibit_read_only)                              \
   212         ? !NILP (Fmemq (textget ((i)->plist, Qread_only),       \
   213                         Vinhibit_read_only))                    \
   214         : !NILP (Vinhibit_read_only))))
   215 
   216 /* Macros to tell whether insertions before or after this interval
   217    should stick to it.  Now we have Vtext_property_default_nonsticky,
   218    so these macros are unreliable now and never used.  */
   219 
   220 #if false
   221 #define FRONT_STICKY_P(i)                               \
   222   (i && ! NILP (textget ((i)->plist, Qfront_sticky)))
   223 #define END_NONSTICKY_P(i)                              \
   224   (i && ! NILP (textget ((i)->plist, Qrear_nonsticky)))
   225 #define FRONT_NONSTICKY_P(i)                            \
   226   (i && ! EQ (Qt, textget ((i)->plist, Qfront_sticky)))
   227 #endif
   228 
   229 /* If PROP is the `invisible' property of a character,
   230    this is 1 if the character should be treated as invisible,
   231    and 2 if it is invisible but with an ellipsis.  */
   232 
   233 #define TEXT_PROP_MEANS_INVISIBLE(prop)                                 \
   234   (EQ (BVAR (current_buffer, invisibility_spec), Qt)                    \
   235    ? !NILP (prop)                                                       \
   236    : invisible_prop (prop, BVAR (current_buffer, invisibility_spec)))
   237 
   238 /* Declared in alloc.c.  */
   239 
   240 extern INTERVAL make_interval (void) ATTRIBUTE_RETURNS_NONNULL;
   241 
   242 /* Declared in intervals.c.  */
   243 
   244 extern INTERVAL create_root_interval (Lisp_Object);
   245 extern void copy_properties (INTERVAL, INTERVAL);
   246 extern bool intervals_equal (INTERVAL, INTERVAL);
   247 extern void traverse_intervals (INTERVAL, ptrdiff_t,
   248                                 void (*) (INTERVAL, Lisp_Object),
   249                                 Lisp_Object);
   250 extern void traverse_intervals_noorder (INTERVAL,
   251                                         void (*) (INTERVAL, void *), void *);
   252 extern INTERVAL split_interval_right (INTERVAL, ptrdiff_t)
   253   ATTRIBUTE_RETURNS_NONNULL;
   254 extern INTERVAL split_interval_left (INTERVAL, ptrdiff_t) ATTRIBUTE_RETURNS_NONNULL;
   255 extern INTERVAL find_interval (INTERVAL, ptrdiff_t);
   256 extern INTERVAL next_interval (INTERVAL);
   257 extern INTERVAL previous_interval (INTERVAL);
   258 extern INTERVAL merge_interval_left (INTERVAL);
   259 extern void offset_intervals (struct buffer *, ptrdiff_t, ptrdiff_t);
   260 extern void graft_intervals_into_buffer (INTERVAL, ptrdiff_t, ptrdiff_t,
   261                                          struct buffer *, bool);
   262 extern void verify_interval_modification (struct buffer *,
   263                                           ptrdiff_t, ptrdiff_t);
   264 extern INTERVAL balance_intervals (INTERVAL);
   265 extern void copy_intervals_to_string (Lisp_Object, struct buffer *,
   266                                              ptrdiff_t, ptrdiff_t);
   267 extern INTERVAL copy_intervals (INTERVAL, ptrdiff_t, ptrdiff_t);
   268 extern bool compare_string_intervals (Lisp_Object, Lisp_Object);
   269 extern Lisp_Object textget (Lisp_Object, Lisp_Object);
   270 extern Lisp_Object lookup_char_property (Lisp_Object, Lisp_Object, bool);
   271 extern void move_if_not_intangible (ptrdiff_t);
   272 extern bool get_property_and_range (ptrdiff_t, Lisp_Object, Lisp_Object *,
   273                                     ptrdiff_t *, ptrdiff_t *, Lisp_Object);
   274 extern Lisp_Object get_local_map (ptrdiff_t, struct buffer *, Lisp_Object);
   275 extern INTERVAL update_interval (INTERVAL, ptrdiff_t);
   276 extern void set_intervals_multibyte (bool);
   277 extern INTERVAL validate_interval_range (Lisp_Object, Lisp_Object *,
   278                                          Lisp_Object *, bool);
   279 extern INTERVAL interval_of (ptrdiff_t, Lisp_Object);
   280 
   281 /* Defined in xdisp.c.  */
   282 extern int invisible_prop (Lisp_Object, Lisp_Object);
   283 
   284 /* Defined in textprop.c.  */
   285 extern Lisp_Object copy_text_properties (Lisp_Object, Lisp_Object,
   286                                          Lisp_Object, Lisp_Object,
   287                                          Lisp_Object, Lisp_Object);
   288 extern Lisp_Object set_text_properties (Lisp_Object, Lisp_Object,
   289                                         Lisp_Object, Lisp_Object,
   290                                         Lisp_Object);
   291 extern void set_text_properties_1 (Lisp_Object, Lisp_Object,
   292                                    Lisp_Object, Lisp_Object, INTERVAL);
   293 
   294 Lisp_Object text_property_list (Lisp_Object, Lisp_Object, Lisp_Object,
   295                                 Lisp_Object);
   296 void add_text_properties_from_list (Lisp_Object, Lisp_Object, Lisp_Object);
   297 Lisp_Object extend_property_ranges (Lisp_Object, Lisp_Object, Lisp_Object);
   298 Lisp_Object get_char_property_and_overlay (Lisp_Object, Lisp_Object,
   299                                            Lisp_Object, Lisp_Object *);
   300 extern int text_property_stickiness (Lisp_Object prop, Lisp_Object pos,
   301                                      Lisp_Object buffer);
   302 
   303 extern void syms_of_textprop (void);
   304 
   305 INLINE_HEADER_END
   306 
   307 #endif /* EMACS_INTERVALS_H */

/* [<][>][^][v][top][bottom][index][help] */