/* Header file for the buffer manipulation primitives.
- Copyright (C) 1985, 1986, 1993, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1993, 1994, 1995 Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#ifdef USE_TEXT_PROPERTIES
#else /* don't support text properties */
-#define SET_PT(position) (current_buffer->text.pt = (position))
-#define TEMP_SET_PT(position) (current_buffer->text.pt = (position))
+#define SET_PT(position) (current_buffer->pt = (position))
+#define TEMP_SET_PT(position) (current_buffer->pt = (position))
-#define BUF_SET_PT(buffer, position) (buffer->text.pt = (position))
-#define BUF_TEMP_SET_PT(buffer, position) (buffer->text.pt = (position))
+#define BUF_SET_PT(buffer, position) (buffer->pt = (position))
+#define BUF_TEMP_SET_PT(buffer, position) (buffer->pt = (position))
#endif /* don't support text properties */
/* Character position of beginning of buffer. */
#define BEG (1)
/* Character position of beginning of accessible range of buffer. */
-#define BEGV (current_buffer->text.begv)
+#define BEGV (current_buffer->begv)
/* Character position of point in buffer. The "+ 0" makes this
not an l-value, so you can't assign to it. Use SET_PT instead. */
-#define PT (current_buffer->text.pt + 0)
+#define PT (current_buffer->pt + 0)
/* Character position of gap in buffer. */
-#define GPT (current_buffer->text.gpt)
+#define GPT (current_buffer->text->gpt)
/* Character position of end of accessible range of buffer. */
-#define ZV (current_buffer->text.zv)
+#define ZV (current_buffer->zv)
/* Character position of end of buffer. */
-#define Z (current_buffer->text.z)
+#define Z (current_buffer->text->z)
/* Is the current buffer narrowed? */
#define NARROWED ((BEGV != BEG) || (ZV != Z))
/* Modification count. */
-#define MODIFF (current_buffer->text.modiff)
+#define MODIFF (current_buffer->text->modiff)
+
+/* Overlay modification count. */
+#define OVERLAY_MODIFF (current_buffer->text->overlay_modiff)
+
+/* Modification count as of last visit or save. */
+#define SAVE_MODIFF (current_buffer->text->save_modiff)
/* Address of beginning of buffer. */
-#define BEG_ADDR (current_buffer->text.beg)
+#define BEG_ADDR (current_buffer->text->beg)
/* Address of beginning of accessible range of buffer. */
-#define BEGV_ADDR (&FETCH_CHAR (current_buffer->text.begv))
+#define BEGV_ADDR (POS_ADDR (current_buffer->begv))
/* Address of point in buffer. */
-#define PT_ADDR (&FETCH_CHAR (current_buffer->text.pt))
+#define PT_ADDR (POS_ADDR (current_buffer->pt))
/* Address of beginning of gap in buffer. */
-#define GPT_ADDR (current_buffer->text.beg + current_buffer->text.gpt - 1)
+#define GPT_ADDR (current_buffer->text->beg + current_buffer->text->gpt - 1)
/* Address of end of gap in buffer. */
-#define GAP_END_ADDR (current_buffer->text.beg + current_buffer->text.gpt + current_buffer->text.gap_size - 1)
+#define GAP_END_ADDR (current_buffer->text->beg + current_buffer->text->gpt + current_buffer->text->gap_size - 1)
/* Address of end of accessible range of buffer. */
-#define ZV_ADDR (&FETCH_CHAR (current_buffer->text.zv))
+#define ZV_ADDR (POS_ADDR (current_buffer->zv))
+
+/* Address of end of buffer. */
+#define Z_ADDR (current_buffer->text->beg + current_buffer->text->gap_size + current_buffer->text->z - 1)
/* Size of gap. */
-#define GAP_SIZE (current_buffer->text.gap_size)
+#define GAP_SIZE (current_buffer->text->gap_size)
/* Now similar macros for a specified buffer.
Note that many of these evaluate the buffer argument more than once. */
#define BUF_BEG(buf) (1)
/* Character position of beginning of accessible range of buffer. */
-#define BUF_BEGV(buf) ((buf)->text.begv)
+#define BUF_BEGV(buf) ((buf)->begv)
/* Character position of point in buffer. */
-#define BUF_PT(buf) ((buf)->text.pt)
+#define BUF_PT(buf) ((buf)->pt)
/* Character position of gap in buffer. */
-#define BUF_GPT(buf) ((buf)->text.gpt)
+#define BUF_GPT(buf) ((buf)->text->gpt)
/* Character position of end of accessible range of buffer. */
-#define BUF_ZV(buf) ((buf)->text.zv)
+#define BUF_ZV(buf) ((buf)->zv)
/* Character position of end of buffer. */
-#define BUF_Z(buf) ((buf)->text.z)
+#define BUF_Z(buf) ((buf)->text->z)
/* Is this buffer narrowed? */
-#define BUF_NARROWED(buf) ((BUF_BEGV(buf) != BUF_BEG(buf)) \
- || (BUF_ZV(buf) != BUF_Z(buf)))
+#define BUF_NARROWED(buf) ((BUF_BEGV (buf) != BUF_BEG (buf)) \
+ || (BUF_ZV (buf) != BUF_Z (buf)))
/* Modification count. */
-#define BUF_MODIFF(buf) ((buf)->text.modiff)
+#define BUF_MODIFF(buf) ((buf)->text->modiff)
+
+/* Modification count as of last visit or save. */
+#define BUF_SAVE_MODIFF(buf) ((buf)->text->save_modiff)
+
+/* Overlay modification count. */
+#define BUF_OVERLAY_MODIFF(buf) ((buf)->text->overlay_modiff)
+
+/* Interval tree of buffer. */
+#define BUF_INTERVALS(buf) ((buf)->text->intervals)
+
+/* Marker chain of buffer. */
+#define BUF_MARKERS(buf) ((buf)->text->markers)
/* Address of beginning of buffer. */
-#define BUF_BEG_ADDR(buf) ((buf)->text.beg)
+#define BUF_BEG_ADDR(buf) ((buf)->text->beg)
+
+/* Address of beginning of gap of buffer. */
+#define BUF_GPT_ADDR(buf) ((buf)->text->beg + (buf)->text->gpt - 1)
+
+/* Address of end of buffer. */
+#define BUF_Z_ADDR(buf) ((buf)->text->beg + (buf)->text->gap_size + (buf)->text->z - 1)
/* Macro for setting the value of BUF_ZV (BUF) to VALUE,
by varying the end of the accessible region. */
-#define SET_BUF_ZV(buf, value) ((buf)->text.zv = (value))
-#define SET_BUF_PT(buf, value) ((buf)->text.pt = (value))
+#define SET_BUF_ZV(buf, value) ((buf)->zv = (value))
+#define SET_BUF_PT(buf, value) ((buf)->pt = (value))
/* Size of gap. */
-#define BUF_GAP_SIZE(buf) ((buf)->text.gap_size)
+#define BUF_GAP_SIZE(buf) ((buf)->text->gap_size)
/* Return the address of character at position POS in buffer BUF.
Note that both arguments can be computed more than once. */
#define BUF_CHAR_ADDRESS(buf, pos) \
-((buf)->text.beg + (pos) - 1 \
- + ((pos) >= (buf)->text.gpt ? (buf)->text.gap_size : 0))
+((buf)->text->beg + (pos) - 1 \
+ + ((pos) >= (buf)->text->gpt ? (buf)->text->gap_size : 0))
/* Convert the address of a char in the buffer into a character position. */
#define PTR_CHAR_POS(ptr) \
-((ptr) - (current_buffer)->text.beg \
- - (ptr - (current_buffer)->text.beg < (unsigned) GPT ? 0 : GAP_SIZE) \
+((ptr) - (current_buffer)->text->beg \
+ - (ptr - (current_buffer)->text->beg < (unsigned) GPT ? 0 : GAP_SIZE) \
+ + 1)
+
+/* Convert the address of a char in the buffer into a character position. */
+#define BUF_PTR_CHAR_POS(buf, ptr) \
+((ptr) - (buf)->text->beg \
+ - (ptr - (buf)->text->beg < (unsigned) BUF_GPT ((buf)) \
+ ? 0 : BUF_GAP_SIZE ((buf))) \
+ 1)
\f
struct buffer_text
{
- unsigned char *beg; /* Actual address of buffer contents. */
- int begv; /* Index of beginning of accessible range. */
- int pt; /* Position of point in buffer. */
- int gpt; /* Index of gap in buffer. */
- int zv; /* Index of end of accessible range. */
- int z; /* Index of end of buffer. */
- int gap_size; /* Size of buffer's gap */
+ unsigned char *beg; /* Actual address of buffer contents. */
+ int gpt; /* Index of gap in buffer. */
+ int z; /* Index of end of buffer. */
+ int gap_size; /* Size of buffer's gap. */
int modiff; /* This counts buffer-modification events
for this buffer. It is incremented for
each such event, and never otherwise
changed. */
+ int save_modiff; /* Previous value of modiff, as of last
+ time buffer visited or saved a file. */
+
+ int overlay_modiff; /* Counts modifications to overlays. */
+
+ /* Properties of this buffer's text -- conditionally compiled. */
+ DECLARE_INTERVALS
+
+ /* The markers that refer to this buffer.
+ This is actually a single marker ---
+ successive elements in its marker `chain'
+ are the other markers referring to this buffer. */
+ Lisp_Object markers;
};
struct buffer
/* Everything before the `name' slot must be of a non-Lisp_Object type,
and every slot after `name' must be a Lisp_Object.
- Check out mark_buffer (alloc.c) to see why.
- */
+ Check out mark_buffer (alloc.c) to see why. */
+
+ EMACS_INT size;
- /* This structure holds the coordinates of the buffer contents. */
- struct buffer_text text;
/* Next buffer, in chain of all buffers including killed buffers.
This chain is used only for garbage collection, in order to
- collect killed buffers properly. */
+ collect killed buffers properly.
+ Note that vectors and most pseudovectors are all on one chain,
+ but buffers are on a separate chain of their own. */
struct buffer *next;
+
+ /* This structure holds the coordinates of the buffer contents
+ in ordinary buffers. In indirect buffers, this is not used. */
+ struct buffer_text own_text;
+
+ /* This points to the `struct buffer_text' that used for this buffer.
+ In an ordinary buffer, this is the own_text field above.
+ In an indirect buffer, this is the own_text field of another buffer. */
+ struct buffer_text *text;
+
+ /* Position of point in buffer. */
+ int pt;
+ /* Index of beginning of accessible range. */
+ int begv;
+ /* Index of end of accessible range. */
+ int zv;
+
+ /* In an indirect buffer, this points to the base buffer.
+ In an ordinary buffer, it is 0. */
+ struct buffer *base_buffer;
+
/* Flags saying which DEFVAR_PER_BUFFER variables
are local to this buffer. */
int local_var_flags;
- /* Value of text.modiff as of when visited file was read or written. */
- int save_modified;
/* Set to the modtime of the visited file when read or written.
-1 means visited file was nonexistent.
0 means visited file modtime unknown; in no case complain
about any mismatch on next save attempt. */
int modtime;
- /* the value of text.modiff at the last auto-save. */
+ /* the value of text->modiff at the last auto-save. */
int auto_save_modified;
/* The time at which we detected a failure to auto-save,
Or -1 if we didn't have a failure. */
int auto_save_failure_time;
/* Position in buffer at which display started
- the last time this buffer was displayed */
+ the last time this buffer was displayed. */
int last_window_start;
- /* Properties of this buffer's text -- conditionally compiled. */
- DECLARE_INTERVALS
+ /* Set nonzero whenever the narrowing is changed in this buffer. */
+ int clip_changed;
- /* This is a special exception -- as this slot should not be
- marked by gc_sweep, and as it is not lisp-accessible as
- a local variable -- so we regard it as not really being of type
- Lisp_Object */
- /* the markers that refer to this buffer.
- This is actually a single marker ---
- successive elements in its marker `chain'
- are the other markers referring to this
- buffer */
- Lisp_Object markers;
+ /* If the long line scan cache is enabled (i.e. the buffer-local
+ variable cache-long-line-scans is non-nil), newline_cache
+ points to the newline cache, and width_run_cache points to the
+ width run cache.
+
+ The newline cache records which stretches of the buffer are
+ known *not* to contain newlines, so that they can be skipped
+ quickly when we search for newlines.
+ The width run cache records which stretches of the buffer are
+ known to contain characters whose widths are all the same. If
+ the width run cache maps a character to a value > 0, that value is
+ the character's width; if it maps a character to zero, we don't
+ know what its width is. This allows compute_motion to process
+ such regions very quickly, using algebra instead of inspecting
+ each character. See also width_table, below. */
+ struct region_cache *newline_cache;
+ struct region_cache *width_run_cache;
/* Everything from here down must be a Lisp_Object */
- /* the name of this buffer */
+ /* The name of this buffer. */
Lisp_Object name;
- /* Nuked: buffer number, assigned when buffer made Lisp_Object number;*/
- /* the name of the file associated with this buffer */
+ /* The name of the file visited in this buffer, or nil. */
Lisp_Object filename;
- /* Dir for expanding relative pathnames */
+ /* Dir for expanding relative file names. */
Lisp_Object directory;
- /* true iff this buffer has been backed
- up (if you write to its associated file
- and it hasn't been backed up, then a
- backup will be made) */
+ /* True iff this buffer has been backed up (if you write to the
+ visited file and it hasn't been backed up, then a backup will
+ be made). */
/* This isn't really used by the C code, so could be deleted. */
Lisp_Object backed_up;
- /* Length of file when last read or saved. */
+ /* Length of file when last read or saved.
+ This is not in the struct buffer_text
+ because it's not used in indirect buffers at all. */
Lisp_Object save_length;
- /* file name used for auto-saving this buffer */
+ /* File name used for auto-saving this buffer.
+ This is not in the struct buffer_text
+ because it's not used in indirect buffers at all. */
Lisp_Object auto_save_file_name;
- /* Non-nil if buffer read-only */
+
+ /* Non-nil if buffer read-only. */
Lisp_Object read_only;
- /* "The mark"; no longer allowed to be nil */
+ /* "The mark". This is a marker which may
+ point into this buffer or may point nowhere. */
Lisp_Object mark;
/* Alist of elements (SYMBOL . VALUE-IN-THIS-BUFFER)
for all per-buffer variables of this buffer. */
Lisp_Object local_var_alist;
-
- /* Symbol naming major mode (eg lisp-mode) */
+ /* Symbol naming major mode (eg, lisp-mode). */
Lisp_Object major_mode;
- /* Pretty name of major mode (eg "Lisp") */
+ /* Pretty name of major mode (eg, "Lisp"). */
Lisp_Object mode_name;
- /* Format string for mode line */
+ /* Mode line element that controls format of mode line. */
Lisp_Object mode_line_format;
- /* Keys that are bound local to this buffer */
+ /* Keys that are bound local to this buffer. */
Lisp_Object keymap;
- /* This buffer's local abbrev table */
+ /* This buffer's local abbrev table. */
Lisp_Object abbrev_table;
- /* This buffer's syntax table. */
+ /* This buffer's syntax table. */
Lisp_Object syntax_table;
+ /* This buffer's category table. */
+ Lisp_Object category_table;
/* Values of several buffer-local variables */
/* tab-width is buffer-local so that redisplay can find it
Lisp_Object tab_width;
Lisp_Object fill_column;
Lisp_Object left_margin;
- /* Function to call when insert space past fill column */
+ /* Function to call when insert space past fill column. */
Lisp_Object auto_fill_function;
-#ifdef MSDOS
- /* nil: text, t: binary. */
+ /* nil: text, t: binary.
+ This value is meaningful only on certain operating systems. */
+ /* Actually, we don't need this flag any more because end-of-line
+ is handled correctly according to the buffer-file-coding-system
+ of the buffer. Just keeping it for backward compatibility. */
Lisp_Object buffer_file_type;
-#endif
- /* String of length 256 mapping each char to its lower-case version. */
+ /* Case table for case-conversion in this buffer.
+ This char-table maps each char into its lower-case version. */
Lisp_Object downcase_table;
- /* String of length 256 mapping each char to its upper-case version. */
+ /* Char-table mapping each char to its upper-case version. */
Lisp_Object upcase_table;
+ /* Char-table for conversion for case-folding search. */
+ Lisp_Object case_canon_table;
+ /* Char-table of equivalences for case-folding search. */
+ Lisp_Object case_eqv_table;
- /* Non-nil means do not display continuation lines */
+ /* Non-nil means do not display continuation lines. */
Lisp_Object truncate_lines;
- /* Non-nil means display ctl chars with uparrow */
+ /* Non-nil means display ctl chars with uparrow. */
Lisp_Object ctl_arrow;
+ /* Non-nil means display text from right to left. */
+ Lisp_Object direction_reversed;
/* Non-nil means do selective display;
- See doc string in syms_of_buffer (buffer.c) for details. */
+ see doc string in syms_of_buffer (buffer.c) for details. */
Lisp_Object selective_display;
#ifndef old
/* Non-nil means show ... at end of line followed by invisible lines. */
Lisp_Object selective_display_ellipses;
#endif
- /* Alist of (FUNCTION . STRING) for each minor mode enabled in buffer. */
+ /* Alist of (FUNCTION . STRING) for each minor mode enabled in buffer. */
Lisp_Object minor_modes;
/* t if "self-insertion" should overwrite; `binary' if it should also
overwrite newlines and tabs - for editing executables and the like. */
Lisp_Object overwrite_mode;
- /* non-nil means abbrev mode is on. Expand abbrevs automatically. */
+ /* non-nil means abbrev mode is on. Expand abbrevs automatically. */
Lisp_Object abbrev_mode;
- /* Display table to use for text in this buffer. */
+ /* Display table to use for text in this buffer. */
Lisp_Object display_table;
- /* Translate table for case-folding search. */
- Lisp_Object case_canon_table;
- /* Inverse translate (equivalence class) table for case-folding search. */
- Lisp_Object case_eqv_table;
- /* Changes in the buffer are recorded here for undo.
- t means don't record anything. */
- Lisp_Object undo_list;
/* t means the mark and region are currently active. */
Lisp_Object mark_active;
+ /* Changes in the buffer are recorded here for undo.
+ t means don't record anything.
+ This information belongs to the base buffer of an indirect buffer,
+ But we can't store it in the struct buffer_text
+ because local variables have to be right in the struct buffer.
+ So we copy it around in set_buffer_internal. */
+ Lisp_Object undo_list;
+
/* List of overlays that end at or before the current center,
in order of end-position. */
Lisp_Object overlays_before;
/* Position where the overlay lists are centered. */
Lisp_Object overlay_center;
-};
+
+ /* Non-nil means the buffer contents are regarded as multi-byte
+ form of characters, not a binary code. */
+ Lisp_Object enable_multibyte_characters;
+
+ /* List of symbols naming the file format used for visited file. */
+ Lisp_Object file_format;
+
+ /* True if the newline position cache and width run cache are
+ enabled. See search.c and indent.c. */
+ Lisp_Object cache_long_line_scans;
+
+ /* If the width run cache is enabled, this table contains the
+ character widths width_run_cache (see above) assumes. When we
+ do a thorough redisplay, we compare this against the buffer's
+ current display table to see whether the display table has
+ affected the widths of any characters. If it has, we
+ invalidate the width run cache, and re-initialize width_table. */
+ Lisp_Object width_table;
+
+ /* In an indirect buffer, or a buffer that is the base of an
+ indirect buffer, this holds a marker that records
+ PT for this buffer when the buffer is not current. */
+ Lisp_Object pt_marker;
+
+ /* In an indirect buffer, or a buffer that is the base of an
+ indirect buffer, this holds a marker that records
+ BEGV for this buffer when the buffer is not current. */
+ Lisp_Object begv_marker;
+
+ /* In an indirect buffer, or a buffer that is the base of an
+ indirect buffer, this holds a marker that records
+ ZV for this buffer when the buffer is not current. */
+ Lisp_Object zv_marker;
+
+ /* This holds the point value before the last scroll operation.
+ Explicitly setting point sets this to nil. */
+ Lisp_Object point_before_scroll;
+
+ /* Truename of the visited file, or nil. */
+ Lisp_Object file_truename;
+
+ /* Invisibility spec of this buffer.
+ t => any non-nil `invisible' property means invisible.
+ A list => `invisible' property means invisible
+ if it is memq in that list. */
+ Lisp_Object invisibility_spec;
+
+ /* This is the last window that was selected with this buffer in it,
+ or nil if that window no longer displays this buffer. */
+ Lisp_Object last_selected_window;
+
+ /* These are so we don't have to recompile everything
+ the next few times we add a new slot. */
+ Lisp_Object extra2, extra3;
+ };
\f
/* This points to the current buffer. */
\f
/* Point in the current buffer. This is an obsolete alias
and should be eliminated. */
-#define point (current_buffer->text.pt + 0)
+#define point (current_buffer->pt + 0)
+
+/* Return the address of position N. No range checking. */
+#define POS_ADDR(n) (((n)>= GPT ? GAP_SIZE : 0) + (n) + BEG_ADDR - 1)
+
+/* Return the byte at position N. No range checking. */
+#define FETCH_BYTE(n) *(POS_ADDR ((n)))
+
+/* Variables used locally in FETCH_MULTIBYTE_CHAR. */
+extern unsigned char *_fetch_multibyte_char_p;
+extern int _fetch_multibyte_char_len;
+
+/* Return character code of multi-byte form at position POS. If POS
+ doesn't point the head of valid multi-byte form, only the byte at
+ POS is returned. No range checking. */
+
+#define FETCH_MULTIBYTE_CHAR(pos) \
+ (_fetch_multibyte_char_p = (((pos) >= GPT ? GAP_SIZE : 0) \
+ + (pos) + BEG_ADDR - 1), \
+ _fetch_multibyte_char_len = ((pos) >= GPT ? ZV : GPT) - (pos), \
+ STRING_CHAR (_fetch_multibyte_char_p, _fetch_multibyte_char_len))
-/* Return character at position n. No range checking. */
-#define FETCH_CHAR(n) *(((n)>= GPT ? GAP_SIZE : 0) + (n) + BEG_ADDR - 1)
+/* Return character at position POS. No range checking. */
+#define FETCH_CHAR(pos) \
+ (!NILP (current_buffer->enable_multibyte_characters) \
+ ? FETCH_MULTIBYTE_CHAR ((pos)) \
+ : FETCH_BYTE ((pos)))
/* BUFFER_CEILING_OF (resp. BUFFER_FLOOR_OF), when applied to n, return
the max (resp. min) p such that
- &FETCH_CHAR (p) - &FETCH_CHAR (n) == p - n */
+ POS_ADDR (p) - POS_ADDR (n) == p - n */
#define BUFFER_CEILING_OF(n) (((n) < GPT && GPT < ZV ? GPT : ZV) - 1)
#define BUFFER_FLOOR_OF(n) (BEGV <= GPT && GPT <= (n) ? GPT : BEGV)
extern void reset_buffer ();
+extern void evaporate_overlays ();
extern Lisp_Object Fbuffer_name ();
extern Lisp_Object Fget_file_buffer ();
+extern Lisp_Object Fnext_overlay_change ();
+extern Lisp_Object Fdelete_overlay ();
-/* Functions to call before and after each text change. */
+/* Functions to call before and after each text change. */
extern Lisp_Object Vbefore_change_function;
extern Lisp_Object Vafter_change_function;
extern Lisp_Object Vbefore_change_functions;
extern Lisp_Object Vafter_change_functions;
extern Lisp_Object Vfirst_change_hook;
+extern Lisp_Object Qbefore_change_functions;
+extern Lisp_Object Qafter_change_functions;
extern Lisp_Object Qfirst_change_hook;
extern Lisp_Object Vdeactivate_mark;
#define OVERLAY_VALID(OV) (OVERLAYP (OV))
/* Return the marker that stands for where OV starts in the buffer. */
-#define OVERLAY_START(OV) (XCONS (XCONS ((OV))->car)->car)
+#define OVERLAY_START(OV) (XOVERLAY (OV)->start)
/* Return the marker that stands for where OV ends in the buffer. */
-#define OVERLAY_END(OV) (XCONS (XCONS ((OV))->car)->cdr)
+#define OVERLAY_END(OV) (XOVERLAY (OV)->end)
/* Return the actual buffer position for the marker P.
We assume you know which buffer it's pointing into. */
-#define OVERLAY_POSITION(P) \
- (XGCTYPE ((P)) == Lisp_Marker ? marker_position ((P)) : (abort (), 0))
+#define OVERLAY_POSITION(P) \
+ (GC_MARKERP (P) ? marker_position (P) : (abort (), 0))
/* Allocation of buffer text. */