Mercurial > hg > xemacs-beta
comparison src/extents.c @ 665:fdefd0186b75
[xemacs-hg @ 2001-09-20 06:28:42 by ben]
The great integral types renaming.
The purpose of this is to rationalize the names used for various
integral types, so that they match their intended uses and follow
consist conventions, and eliminate types that were not semantically
different from each other.
The conventions are:
-- All integral types that measure quantities of anything are
signed. Some people disagree vociferously with this, but their
arguments are mostly theoretical, and are vastly outweighed by
the practical headaches of mixing signed and unsigned values,
and more importantly by the far increased likelihood of
inadvertent bugs: Because of the broken "viral" nature of
unsigned quantities in C (operations involving mixed
signed/unsigned are done unsigned, when exactly the opposite is
nearly always wanted), even a single error in declaring a
quantity unsigned that should be signed, or even the even more
subtle error of comparing signed and unsigned values and
forgetting the necessary cast, can be catastrophic, as
comparisons will yield wrong results. -Wsign-compare is turned
on specifically to catch this, but this tends to result in a
great number of warnings when mixing signed and unsigned, and
the casts are annoying. More has been written on this
elsewhere.
-- All such quantity types just mentioned boil down to EMACS_INT,
which is 32 bits on 32-bit machines and 64 bits on 64-bit
machines. This is guaranteed to be the same size as Lisp
objects of type `int', and (as far as I can tell) of size_t
(unsigned!) and ssize_t. The only type below that is not an
EMACS_INT is Hashcode, which is an unsigned value of the same
size as EMACS_INT.
-- Type names should be relatively short (no more than 10
characters or so), with the first letter capitalized and no
underscores if they can at all be avoided.
-- "count" == a zero-based measurement of some quantity. Includes
sizes, offsets, and indexes.
-- "bpos" == a one-based measurement of a position in a buffer.
"Charbpos" and "Bytebpos" count text in the buffer, rather than
bytes in memory; thus Bytebpos does not directly correspond to
the memory representation. Use "Membpos" for this.
-- "Char" refers to internal-format characters, not to the C type
"char", which is really a byte.
-- For the actual name changes, see the script below.
I ran the following script to do the conversion. (NOTE: This script
is idempotent. You can safely run it multiple times and it will
not screw up previous results -- in fact, it will do nothing if
nothing has changed. Thus, it can be run repeatedly as necessary
to handle patches coming in from old workspaces, or old branches.)
There are two tags, just before and just after the change:
`pre-integral-type-rename' and `post-integral-type-rename'. When
merging code from the main trunk into a branch, the best thing to
do is first merge up to `pre-integral-type-rename', then apply the
script and associated changes, then merge from
`post-integral-type-change' to the present. (Alternatively, just do
the merging in one operation; but you may then have a lot of
conflicts needing to be resolved by hand.)
Script `fixtypes.sh' follows:
----------------------------------- cut ------------------------------------
files="*.[ch] s/*.h m/*.h config.h.in ../configure.in Makefile.in.in ../lib-src/*.[ch] ../lwlib/*.[ch]"
gr Memory_Count Bytecount $files
gr Lstream_Data_Count Bytecount $files
gr Element_Count Elemcount $files
gr Hash_Code Hashcode $files
gr extcount bytecount $files
gr bufpos charbpos $files
gr bytind bytebpos $files
gr memind membpos $files
gr bufbyte intbyte $files
gr Extcount Bytecount $files
gr Bufpos Charbpos $files
gr Bytind Bytebpos $files
gr Memind Membpos $files
gr Bufbyte Intbyte $files
gr EXTCOUNT BYTECOUNT $files
gr BUFPOS CHARBPOS $files
gr BYTIND BYTEBPOS $files
gr MEMIND MEMBPOS $files
gr BUFBYTE INTBYTE $files
gr MEMORY_COUNT BYTECOUNT $files
gr LSTREAM_DATA_COUNT BYTECOUNT $files
gr ELEMENT_COUNT ELEMCOUNT $files
gr HASH_CODE HASHCODE $files
----------------------------------- cut ------------------------------------
`fixtypes.sh' is a Bourne-shell script; it uses 'gr':
----------------------------------- cut ------------------------------------
#!/bin/sh
# Usage is like this:
# gr FROM TO FILES ...
# globally replace FROM with TO in FILES. FROM and TO are regular expressions.
# backup files are stored in the `backup' directory.
from="$1"
to="$2"
shift 2
echo ${1+"$@"} | xargs global-replace "s/$from/$to/g"
----------------------------------- cut ------------------------------------
`gr' in turn uses a Perl script to do its real work,
`global-replace', which follows:
----------------------------------- cut ------------------------------------
: #-*- Perl -*-
### global-modify --- modify the contents of a file by a Perl expression
## Copyright (C) 1999 Martin Buchholz.
## Copyright (C) 2001 Ben Wing.
## Authors: Martin Buchholz <martin@xemacs.org>, Ben Wing <ben@xemacs.org>
## Maintainer: Ben Wing <ben@xemacs.org>
## Current Version: 1.0, May 5, 2001
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with XEmacs; see the file COPYING. If not, write to the Free
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
eval 'exec perl -w -S $0 ${1+"$@"}'
if 0;
use strict;
use FileHandle;
use Carp;
use Getopt::Long;
use File::Basename;
(my $myName = $0) =~ s@.*/@@; my $usage="
Usage: $myName [--help] [--backup-dir=DIR] [--line-mode] [--hunk-mode]
PERLEXPR FILE ...
Globally modify a file, either line by line or in one big hunk.
Typical usage is like this:
[with GNU print, GNU xargs: guaranteed to handle spaces, quotes, etc.
in file names]
find . -name '*.[ch]' -print0 | xargs -0 $0 's/\bCONST\b/const/g'\n
[with non-GNU print, xargs]
find . -name '*.[ch]' -print | xargs $0 's/\bCONST\b/const/g'\n
The file is read in, either line by line (with --line-mode specified)
or in one big hunk (with --hunk-mode specified; it's the default), and
the Perl expression is then evalled with \$_ set to the line or hunk of
text, including the terminating newline if there is one. It should
destructively modify the value there, storing the changed result in \$_.
Files in which any modifications are made are backed up to the directory
specified using --backup-dir, or to `backup' by default. To disable this,
use --backup-dir= with no argument.
Hunk mode is the default because it is MUCH MUCH faster than line-by-line.
Use line-by-line only when it matters, e.g. you want to do a replacement
only once per line (the default without the `g' argument). Conversely,
when using hunk mode, *ALWAYS* use `g'; otherwise, you will only make one
replacement in the entire file!
";
my %options = ();
$Getopt::Long::ignorecase = 0;
&GetOptions (
\%options,
'help', 'backup-dir=s', 'line-mode', 'hunk-mode',
);
die $usage if $options{"help"} or @ARGV <= 1;
my $code = shift;
die $usage if grep (-d || ! -w, @ARGV);
sub SafeOpen {
open ((my $fh = new FileHandle), $_[0]);
confess "Can't open $_[0]: $!" if ! defined $fh;
return $fh;
}
sub SafeClose {
close $_[0] or confess "Can't close $_[0]: $!";
}
sub FileContents {
my $fh = SafeOpen ("< $_[0]");
my $olddollarslash = $/;
local $/ = undef;
my $contents = <$fh>;
$/ = $olddollarslash;
return $contents;
}
sub WriteStringToFile {
my $fh = SafeOpen ("> $_[0]");
binmode $fh;
print $fh $_[1] or confess "$_[0]: $!\n";
SafeClose $fh;
}
foreach my $file (@ARGV) {
my $changed_p = 0;
my $new_contents = "";
if ($options{"line-mode"}) {
my $fh = SafeOpen $file;
while (<$fh>) {
my $save_line = $_;
eval $code;
$changed_p = 1 if $save_line ne $_;
$new_contents .= $_;
}
} else {
my $orig_contents = $_ = FileContents $file;
eval $code;
if ($_ ne $orig_contents) {
$changed_p = 1;
$new_contents = $_;
}
}
if ($changed_p) {
my $backdir = $options{"backup-dir"};
$backdir = "backup" if !defined ($backdir);
if ($backdir) {
my ($name, $path, $suffix) = fileparse ($file, "");
my $backfulldir = $path . $backdir;
my $backfile = "$backfulldir/$name";
mkdir $backfulldir, 0755 unless -d $backfulldir;
print "modifying $file (original saved in $backfile)\n";
rename $file, $backfile;
}
WriteStringToFile ($file, $new_contents);
}
}
----------------------------------- cut ------------------------------------
In addition to those programs, I needed to fix up a few other
things, particularly relating to the duplicate definitions of
types, now that some types merged with others. Specifically:
1. in lisp.h, removed duplicate declarations of Bytecount. The
changed code should now look like this: (In each code snippet
below, the first and last lines are the same as the original, as
are all lines outside of those lines. That allows you to locate
the section to be replaced, and replace the stuff in that
section, verifying that there isn't anything new added that
would need to be kept.)
--------------------------------- snip -------------------------------------
/* Counts of bytes or chars */
typedef EMACS_INT Bytecount;
typedef EMACS_INT Charcount;
/* Counts of elements */
typedef EMACS_INT Elemcount;
/* Hash codes */
typedef unsigned long Hashcode;
/* ------------------------ dynamic arrays ------------------- */
--------------------------------- snip -------------------------------------
2. in lstream.h, removed duplicate declaration of Bytecount.
Rewrote the comment about this type. The changed code should
now look like this:
--------------------------------- snip -------------------------------------
#endif
/* The have been some arguments over the what the type should be that
specifies a count of bytes in a data block to be written out or read in,
using Lstream_read(), Lstream_write(), and related functions.
Originally it was long, which worked fine; Martin "corrected" these to
size_t and ssize_t on the grounds that this is theoretically cleaner and
is in keeping with the C standards. Unfortunately, this practice is
horribly error-prone due to design flaws in the way that mixed
signed/unsigned arithmetic happens. In fact, by doing this change,
Martin introduced a subtle but fatal error that caused the operation of
sending large mail messages to the SMTP server under Windows to fail.
By putting all values back to be signed, avoiding any signed/unsigned
mixing, the bug immediately went away. The type then in use was
Lstream_Data_Count, so that it be reverted cleanly if a vote came to
that. Now it is Bytecount.
Some earlier comments about why the type must be signed: This MUST BE
SIGNED, since it also is used in functions that return the number of
bytes actually read to or written from in an operation, and these
functions can return -1 to signal error.
Note that the standard Unix read() and write() functions define the
count going in as a size_t, which is UNSIGNED, and the count going
out as an ssize_t, which is SIGNED. This is a horrible design
flaw. Not only is it highly likely to lead to logic errors when a
-1 gets interpreted as a large positive number, but operations are
bound to fail in all sorts of horrible ways when a number in the
upper-half of the size_t range is passed in -- this number is
unrepresentable as an ssize_t, so code that checks to see how many
bytes are actually written (which is mandatory if you are dealing
with certain types of devices) will get completely screwed up.
--ben
*/
typedef enum lstream_buffering
--------------------------------- snip -------------------------------------
3. in dumper.c, there are four places, all inside of switch()
statements, where XD_BYTECOUNT appears twice as a case tag. In
each case, the two case blocks contain identical code, and you
should *REMOVE THE SECOND* and leave the first.
author | ben |
---|---|
date | Thu, 20 Sep 2001 06:31:11 +0000 |
parents | b39c14581166 |
children | 943eaba38521 |
comparison
equal
deleted
inserted
replaced
664:6e99cc8c6ca5 | 665:fdefd0186b75 |
---|---|
263 | 263 |
264 static Gap_Array_Marker *gap_array_marker_freelist; | 264 static Gap_Array_Marker *gap_array_marker_freelist; |
265 | 265 |
266 /* Convert a "memory position" (i.e. taking the gap into account) into | 266 /* Convert a "memory position" (i.e. taking the gap into account) into |
267 the address of the element at (i.e. after) that position. "Memory | 267 the address of the element at (i.e. after) that position. "Memory |
268 positions" are only used internally and are of type Memind. | 268 positions" are only used internally and are of type Membpos. |
269 "Array positions" are used externally and are of type int. */ | 269 "Array positions" are used externally and are of type int. */ |
270 #define GAP_ARRAY_MEMEL_ADDR(ga, memel) ((ga)->array + (ga)->elsize*(memel)) | 270 #define GAP_ARRAY_MEMEL_ADDR(ga, memel) ((ga)->array + (ga)->elsize*(memel)) |
271 | 271 |
272 /* Number of elements currently in a gap array */ | 272 /* Number of elements currently in a gap array */ |
273 #define GAP_ARRAY_NUM_ELS(ga) ((ga)->numels) | 273 #define GAP_ARRAY_NUM_ELS(ga) ((ga)->numels) |
356 /* ------------------------------- */ | 356 /* ------------------------------- */ |
357 | 357 |
358 typedef struct stack_of_extents | 358 typedef struct stack_of_extents |
359 { | 359 { |
360 Extent_List *extents; | 360 Extent_List *extents; |
361 Memind pos; /* Position of stack of extents. EXTENTS is the list of | 361 Membpos pos; /* Position of stack of extents. EXTENTS is the list of |
362 all extents that overlap this position. This position | 362 all extents that overlap this position. This position |
363 can be -1 if the stack of extents is invalid (this | 363 can be -1 if the stack of extents is invalid (this |
364 happens when a buffer is first created or a string's | 364 happens when a buffer is first created or a string's |
365 stack of extents is created [a string's stack of extents | 365 stack of extents is created [a string's stack of extents |
366 is nuked when a GC occurs, to conserve memory]). */ | 366 is nuked when a GC occurs, to conserve memory]). */ |
370 /* map-extents */ | 370 /* map-extents */ |
371 /* ------------------------------- */ | 371 /* ------------------------------- */ |
372 | 372 |
373 typedef int Endpoint_Index; | 373 typedef int Endpoint_Index; |
374 | 374 |
375 #define memind_to_startind(x, start_open) \ | 375 #define membpos_to_startind(x, start_open) \ |
376 ((Endpoint_Index) (((x) << 1) + !!(start_open))) | 376 ((Endpoint_Index) (((x) << 1) + !!(start_open))) |
377 #define memind_to_endind(x, end_open) \ | 377 #define membpos_to_endind(x, end_open) \ |
378 ((Endpoint_Index) (((x) << 1) - !!(end_open))) | 378 ((Endpoint_Index) (((x) << 1) - !!(end_open))) |
379 | 379 |
380 /* Combination macros */ | 380 /* Combination macros */ |
381 #define bytind_to_startind(buf, x, start_open) \ | 381 #define bytebpos_to_startind(buf, x, start_open) \ |
382 memind_to_startind (bytind_to_memind (buf, x), start_open) | 382 membpos_to_startind (bytebpos_to_membpos (buf, x), start_open) |
383 #define bytind_to_endind(buf, x, end_open) \ | 383 #define bytebpos_to_endind(buf, x, end_open) \ |
384 memind_to_endind (bytind_to_memind (buf, x), end_open) | 384 membpos_to_endind (bytebpos_to_membpos (buf, x), end_open) |
385 | 385 |
386 /* ------------------------------- */ | 386 /* ------------------------------- */ |
387 /* buffer-or-string primitives */ | 387 /* buffer-or-string primitives */ |
388 /* ------------------------------- */ | 388 /* ------------------------------- */ |
389 | 389 |
390 /* Similar for Bytinds and start/end indices. */ | 390 /* Similar for Bytebposs and start/end indices. */ |
391 | 391 |
392 #define buffer_or_string_bytind_to_startind(obj, ind, start_open) \ | 392 #define buffer_or_string_bytebpos_to_startind(obj, ind, start_open) \ |
393 memind_to_startind (buffer_or_string_bytind_to_memind (obj, ind), \ | 393 membpos_to_startind (buffer_or_string_bytebpos_to_membpos (obj, ind), \ |
394 start_open) | 394 start_open) |
395 | 395 |
396 #define buffer_or_string_bytind_to_endind(obj, ind, end_open) \ | 396 #define buffer_or_string_bytebpos_to_endind(obj, ind, end_open) \ |
397 memind_to_endind (buffer_or_string_bytind_to_memind (obj, ind), \ | 397 membpos_to_endind (buffer_or_string_bytebpos_to_membpos (obj, ind), \ |
398 end_open) | 398 end_open) |
399 | 399 |
400 /* ------------------------------- */ | 400 /* ------------------------------- */ |
401 /* Lisp-level functions */ | 401 /* Lisp-level functions */ |
402 /* ------------------------------- */ | 402 /* ------------------------------- */ |
485 | 485 |
486 /* Adjust the gap array markers in the range (FROM, TO]. Parallel to | 486 /* Adjust the gap array markers in the range (FROM, TO]. Parallel to |
487 adjust_markers() in insdel.c. */ | 487 adjust_markers() in insdel.c. */ |
488 | 488 |
489 static void | 489 static void |
490 gap_array_adjust_markers (Gap_Array *ga, Memind from, | 490 gap_array_adjust_markers (Gap_Array *ga, Membpos from, |
491 Memind to, int amount) | 491 Membpos to, int amount) |
492 { | 492 { |
493 Gap_Array_Marker *m; | 493 Gap_Array_Marker *m; |
494 | 494 |
495 for (m = ga->markers; m; m = m->next) | 495 for (m = ga->markers; m; m = m->next) |
496 m->pos = do_marker_adjustment (m->pos, from, to, amount); | 496 m->pos = do_marker_adjustment (m->pos, from, to, amount); |
509 if (pos < gap) | 509 if (pos < gap) |
510 { | 510 { |
511 memmove (GAP_ARRAY_MEMEL_ADDR (ga, pos + gapsize), | 511 memmove (GAP_ARRAY_MEMEL_ADDR (ga, pos + gapsize), |
512 GAP_ARRAY_MEMEL_ADDR (ga, pos), | 512 GAP_ARRAY_MEMEL_ADDR (ga, pos), |
513 (gap - pos)*ga->elsize); | 513 (gap - pos)*ga->elsize); |
514 gap_array_adjust_markers (ga, (Memind) pos, (Memind) gap, | 514 gap_array_adjust_markers (ga, (Membpos) pos, (Membpos) gap, |
515 gapsize); | 515 gapsize); |
516 } | 516 } |
517 else if (pos > gap) | 517 else if (pos > gap) |
518 { | 518 { |
519 memmove (GAP_ARRAY_MEMEL_ADDR (ga, gap), | 519 memmove (GAP_ARRAY_MEMEL_ADDR (ga, gap), |
520 GAP_ARRAY_MEMEL_ADDR (ga, gap + gapsize), | 520 GAP_ARRAY_MEMEL_ADDR (ga, gap + gapsize), |
521 (pos - gap)*ga->elsize); | 521 (pos - gap)*ga->elsize); |
522 gap_array_adjust_markers (ga, (Memind) (gap + gapsize), | 522 gap_array_adjust_markers (ga, (Membpos) (gap + gapsize), |
523 (Memind) (pos + gapsize), - gapsize); | 523 (Membpos) (pos + gapsize), - gapsize); |
524 } | 524 } |
525 ga->gap = pos; | 525 ga->gap = pos; |
526 } | 526 } |
527 | 527 |
528 /* Make the gap INCREMENT characters longer. Parallel to make_gap() in | 528 /* Make the gap INCREMENT characters longer. Parallel to make_gap() in |
773 | 773 |
774 An out-of-range value for POS is allowed, and guarantees that the | 774 An out-of-range value for POS is allowed, and guarantees that the |
775 position at the beginning or end of the extent list is returned. */ | 775 position at the beginning or end of the extent list is returned. */ |
776 | 776 |
777 static int | 777 static int |
778 extent_list_locate_from_pos (Extent_List *el, Memind pos, int endp) | 778 extent_list_locate_from_pos (Extent_List *el, Membpos pos, int endp) |
779 { | 779 { |
780 struct extent fake_extent; | 780 struct extent fake_extent; |
781 /* | 781 /* |
782 | 782 |
783 Note that if we search for [POS, POS], then we get the following: | 783 Note that if we search for [POS, POS], then we get the following: |
797 } | 797 } |
798 | 798 |
799 /* Return the extent at POS. */ | 799 /* Return the extent at POS. */ |
800 | 800 |
801 static EXTENT | 801 static EXTENT |
802 extent_list_at (Extent_List *el, Memind pos, int endp) | 802 extent_list_at (Extent_List *el, Membpos pos, int endp) |
803 { | 803 { |
804 Gap_Array *ga = endp ? el->end : el->start; | 804 Gap_Array *ga = endp ? el->end : el->start; |
805 | 805 |
806 assert (pos >= 0 && pos < GAP_ARRAY_NUM_ELS (ga)); | 806 assert (pos >= 0 && pos < GAP_ARRAY_NUM_ELS (ga)); |
807 return EXTENT_GAP_ARRAY_AT (ga, pos); | 807 return EXTENT_GAP_ARRAY_AT (ga, pos); |
1296 { | 1296 { |
1297 printf ("No SOE"); | 1297 printf ("No SOE"); |
1298 return; | 1298 return; |
1299 } | 1299 } |
1300 sel = soe->extents; | 1300 sel = soe->extents; |
1301 printf ("SOE pos is %d (memind %d)\n", | 1301 printf ("SOE pos is %d (membpos %d)\n", |
1302 soe->pos < 0 ? soe->pos : | 1302 soe->pos < 0 ? soe->pos : |
1303 buffer_or_string_memind_to_bytind (obj, soe->pos), | 1303 buffer_or_string_membpos_to_bytebpos (obj, soe->pos), |
1304 soe->pos); | 1304 soe->pos); |
1305 for (endp = 0; endp < 2; endp++) | 1305 for (endp = 0; endp < 2; endp++) |
1306 { | 1306 { |
1307 printf (endp ? "SOE end:" : "SOE start:"); | 1307 printf (endp ? "SOE end:" : "SOE start:"); |
1308 for (i = 0; i < extent_list_num_els (sel); i++) | 1308 for (i = 0; i < extent_list_num_els (sel); i++) |
1373 } | 1373 } |
1374 | 1374 |
1375 /* Move OBJ's stack of extents to lie over the specified position. */ | 1375 /* Move OBJ's stack of extents to lie over the specified position. */ |
1376 | 1376 |
1377 static void | 1377 static void |
1378 soe_move (Lisp_Object obj, Memind pos) | 1378 soe_move (Lisp_Object obj, Membpos pos) |
1379 { | 1379 { |
1380 Stack_Of_Extents *soe = buffer_or_string_stack_of_extents_force (obj); | 1380 Stack_Of_Extents *soe = buffer_or_string_stack_of_extents_force (obj); |
1381 Extent_List *sel = soe->extents; | 1381 Extent_List *sel = soe->extents; |
1382 int numsoe = extent_list_num_els (sel); | 1382 int numsoe = extent_list_num_els (sel); |
1383 Extent_List *bel = buffer_or_string_extent_list (obj); | 1383 Extent_List *bel = buffer_or_string_extent_list (obj); |
1387 #ifdef ERROR_CHECK_EXTENTS | 1387 #ifdef ERROR_CHECK_EXTENTS |
1388 assert (bel); | 1388 assert (bel); |
1389 #endif | 1389 #endif |
1390 | 1390 |
1391 #ifdef SOE_DEBUG | 1391 #ifdef SOE_DEBUG |
1392 printf ("Moving SOE from %d (memind %d) to %d (memind %d)\n", | 1392 printf ("Moving SOE from %d (membpos %d) to %d (membpos %d)\n", |
1393 soe->pos < 0 ? soe->pos : | 1393 soe->pos < 0 ? soe->pos : |
1394 buffer_or_string_memind_to_bytind (obj, soe->pos), soe->pos, | 1394 buffer_or_string_membpos_to_bytebpos (obj, soe->pos), soe->pos, |
1395 buffer_or_string_memind_to_bytind (obj, pos), pos); | 1395 buffer_or_string_membpos_to_bytebpos (obj, pos), pos); |
1396 #endif | 1396 #endif |
1397 if (soe->pos < pos) | 1397 if (soe->pos < pos) |
1398 { | 1398 { |
1399 direction = 1; | 1399 direction = 1; |
1400 endp = 0; | 1400 endp = 0; |
1531 /* ------------------------------- */ | 1531 /* ------------------------------- */ |
1532 | 1532 |
1533 /* Return the start (endp == 0) or end (endp == 1) of an extent as | 1533 /* Return the start (endp == 0) or end (endp == 1) of an extent as |
1534 a byte index. If you want the value as a memory index, use | 1534 a byte index. If you want the value as a memory index, use |
1535 extent_endpoint(). If you want the value as a buffer position, | 1535 extent_endpoint(). If you want the value as a buffer position, |
1536 use extent_endpoint_bufpos(). */ | 1536 use extent_endpoint_charbpos(). */ |
1537 | 1537 |
1538 static Bytind | 1538 static Bytebpos |
1539 extent_endpoint_bytind (EXTENT extent, int endp) | 1539 extent_endpoint_bytebpos (EXTENT extent, int endp) |
1540 { | 1540 { |
1541 assert (EXTENT_LIVE_P (extent)); | 1541 assert (EXTENT_LIVE_P (extent)); |
1542 assert (!extent_detached_p (extent)); | 1542 assert (!extent_detached_p (extent)); |
1543 { | 1543 { |
1544 Memind i = endp ? extent_end (extent) : extent_start (extent); | 1544 Membpos i = endp ? extent_end (extent) : extent_start (extent); |
1545 Lisp_Object obj = extent_object (extent); | 1545 Lisp_Object obj = extent_object (extent); |
1546 return buffer_or_string_memind_to_bytind (obj, i); | 1546 return buffer_or_string_membpos_to_bytebpos (obj, i); |
1547 } | 1547 } |
1548 } | 1548 } |
1549 | 1549 |
1550 static Bufpos | 1550 static Charbpos |
1551 extent_endpoint_bufpos (EXTENT extent, int endp) | 1551 extent_endpoint_charbpos (EXTENT extent, int endp) |
1552 { | 1552 { |
1553 assert (EXTENT_LIVE_P (extent)); | 1553 assert (EXTENT_LIVE_P (extent)); |
1554 assert (!extent_detached_p (extent)); | 1554 assert (!extent_detached_p (extent)); |
1555 { | 1555 { |
1556 Memind i = endp ? extent_end (extent) : extent_start (extent); | 1556 Membpos i = endp ? extent_end (extent) : extent_start (extent); |
1557 Lisp_Object obj = extent_object (extent); | 1557 Lisp_Object obj = extent_object (extent); |
1558 return buffer_or_string_memind_to_bufpos (obj, i); | 1558 return buffer_or_string_membpos_to_charbpos (obj, i); |
1559 } | 1559 } |
1560 } | 1560 } |
1561 | 1561 |
1562 /* A change to an extent occurred that will change the display, so | 1562 /* A change to an extent occurred that will change the display, so |
1563 notify redisplay. Maybe also recurse over all the extent's | 1563 notify redisplay. Maybe also recurse over all the extent's |
1617 only extents attached to buffers have changed. */ | 1617 only extents attached to buffers have changed. */ |
1618 | 1618 |
1619 if (!in_modeline_generation) | 1619 if (!in_modeline_generation) |
1620 MARK_EXTENTS_CHANGED; | 1620 MARK_EXTENTS_CHANGED; |
1621 gutter_extent_signal_changed_region_maybe (object, | 1621 gutter_extent_signal_changed_region_maybe (object, |
1622 extent_endpoint_bufpos (extent, 0), | 1622 extent_endpoint_charbpos (extent, 0), |
1623 extent_endpoint_bufpos (extent, 1)); | 1623 extent_endpoint_charbpos (extent, 1)); |
1624 } | 1624 } |
1625 else if (BUFFERP (object)) | 1625 else if (BUFFERP (object)) |
1626 { | 1626 { |
1627 struct buffer *b; | 1627 struct buffer *b; |
1628 b = XBUFFER (object); | 1628 b = XBUFFER (object); |
1629 BUF_FACECHANGE (b)++; | 1629 BUF_FACECHANGE (b)++; |
1630 MARK_EXTENTS_CHANGED; | 1630 MARK_EXTENTS_CHANGED; |
1631 if (invisibility_change) | 1631 if (invisibility_change) |
1632 MARK_CLIP_CHANGED; | 1632 MARK_CLIP_CHANGED; |
1633 buffer_extent_signal_changed_region (b, | 1633 buffer_extent_signal_changed_region (b, |
1634 extent_endpoint_bufpos (extent, 0), | 1634 extent_endpoint_charbpos (extent, 0), |
1635 extent_endpoint_bufpos (extent, 1)); | 1635 extent_endpoint_charbpos (extent, 1)); |
1636 } | 1636 } |
1637 } | 1637 } |
1638 | 1638 |
1639 /* A change to an extent occurred that might affect redisplay. | 1639 /* A change to an extent occurred that might affect redisplay. |
1640 This is called when properties such as the endpoints, the layout, | 1640 This is called when properties such as the endpoints, the layout, |
1825 See the comments at map_extents() for info on the overlap rule. | 1825 See the comments at map_extents() for info on the overlap rule. |
1826 Assumes that all validation on the extent and buffer positions has | 1826 Assumes that all validation on the extent and buffer positions has |
1827 already been performed (see Fextent_in_region_p ()). | 1827 already been performed (see Fextent_in_region_p ()). |
1828 */ | 1828 */ |
1829 static int | 1829 static int |
1830 extent_in_region_p (EXTENT extent, Bytind from, Bytind to, | 1830 extent_in_region_p (EXTENT extent, Bytebpos from, Bytebpos to, |
1831 unsigned int flags) | 1831 unsigned int flags) |
1832 { | 1832 { |
1833 Lisp_Object obj = extent_object (extent); | 1833 Lisp_Object obj = extent_object (extent); |
1834 Endpoint_Index start, end, exs, exe; | 1834 Endpoint_Index start, end, exs, exe; |
1835 int start_open, end_open; | 1835 int start_open, end_open; |
1861 case ME_ALL_EXTENTS_CLOSED_OPEN: start_open = 0, end_open = 1; break; | 1861 case ME_ALL_EXTENTS_CLOSED_OPEN: start_open = 0, end_open = 1; break; |
1862 case ME_ALL_EXTENTS_OPEN_CLOSED: start_open = 1, end_open = 0; break; | 1862 case ME_ALL_EXTENTS_OPEN_CLOSED: start_open = 1, end_open = 0; break; |
1863 default: abort(); return 0; | 1863 default: abort(); return 0; |
1864 } | 1864 } |
1865 | 1865 |
1866 start = buffer_or_string_bytind_to_startind (obj, from, | 1866 start = buffer_or_string_bytebpos_to_startind (obj, from, |
1867 flags & ME_START_OPEN); | 1867 flags & ME_START_OPEN); |
1868 end = buffer_or_string_bytind_to_endind (obj, to, ! (flags & ME_END_CLOSED)); | 1868 end = buffer_or_string_bytebpos_to_endind (obj, to, ! (flags & ME_END_CLOSED)); |
1869 exs = memind_to_startind (extent_start (extent), start_open); | 1869 exs = membpos_to_startind (extent_start (extent), start_open); |
1870 exe = memind_to_endind (extent_end (extent), end_open); | 1870 exe = membpos_to_endind (extent_end (extent), end_open); |
1871 | 1871 |
1872 /* It's easy to determine whether an extent lies *outside* the | 1872 /* It's easy to determine whether an extent lies *outside* the |
1873 region -- just determine whether it's completely before | 1873 region -- just determine whether it's completely before |
1874 or completely after the region. Reject all such extents, so | 1874 or completely after the region. Reject all such extents, so |
1875 we're now left with only the extents that overlap the region. | 1875 we're now left with only the extents that overlap the region. |
1945 Furthermore, the results might be a little less sensible than | 1945 Furthermore, the results might be a little less sensible than |
1946 the logic below. */ | 1946 the logic below. */ |
1947 | 1947 |
1948 | 1948 |
1949 static void | 1949 static void |
1950 map_extents_bytind (Bytind from, Bytind to, map_extents_fun fn, void *arg, | 1950 map_extents_bytebpos (Bytebpos from, Bytebpos to, map_extents_fun fn, void *arg, |
1951 Lisp_Object obj, EXTENT after, unsigned int flags) | 1951 Lisp_Object obj, EXTENT after, unsigned int flags) |
1952 { | 1952 { |
1953 Memind st, en; /* range we're mapping over */ | 1953 Membpos st, en; /* range we're mapping over */ |
1954 EXTENT range = 0; /* extent for this, if ME_MIGHT_MODIFY_TEXT */ | 1954 EXTENT range = 0; /* extent for this, if ME_MIGHT_MODIFY_TEXT */ |
1955 Extent_List *el = 0; /* extent list we're iterating over */ | 1955 Extent_List *el = 0; /* extent list we're iterating over */ |
1956 Extent_List_Marker *posm = 0; /* marker for extent list, | 1956 Extent_List_Marker *posm = 0; /* marker for extent list, |
1957 if ME_MIGHT_MODIFY_EXTENTS */ | 1957 if ME_MIGHT_MODIFY_EXTENTS */ |
1958 /* count and struct for unwind-protect, if ME_MIGHT_THROW */ | 1958 /* count and struct for unwind-protect, if ME_MIGHT_THROW */ |
1976 el = buffer_or_string_extent_list (obj); | 1976 el = buffer_or_string_extent_list (obj); |
1977 if (!el || !extent_list_num_els(el)) | 1977 if (!el || !extent_list_num_els(el)) |
1978 return; | 1978 return; |
1979 el = 0; | 1979 el = 0; |
1980 | 1980 |
1981 st = buffer_or_string_bytind_to_memind (obj, from); | 1981 st = buffer_or_string_bytebpos_to_membpos (obj, from); |
1982 en = buffer_or_string_bytind_to_memind (obj, to); | 1982 en = buffer_or_string_bytebpos_to_membpos (obj, to); |
1983 | 1983 |
1984 if (flags & ME_MIGHT_MODIFY_TEXT) | 1984 if (flags & ME_MIGHT_MODIFY_TEXT) |
1985 { | 1985 { |
1986 /* The mapping function might change the text in the buffer, | 1986 /* The mapping function might change the text in the buffer, |
1987 so make an internal extent to hold the range we're mapping | 1987 so make an internal extent to hold the range we're mapping |
2246 | 2246 |
2247 /* ----- Now actually call the function ----- */ | 2247 /* ----- Now actually call the function ----- */ |
2248 | 2248 |
2249 obj2 = extent_object (e); | 2249 obj2 = extent_object (e); |
2250 if (extent_in_region_p (e, | 2250 if (extent_in_region_p (e, |
2251 buffer_or_string_memind_to_bytind (obj2, | 2251 buffer_or_string_membpos_to_bytebpos (obj2, |
2252 st), | 2252 st), |
2253 buffer_or_string_memind_to_bytind (obj2, | 2253 buffer_or_string_membpos_to_bytebpos (obj2, |
2254 en), | 2254 en), |
2255 flags)) | 2255 flags)) |
2256 { | 2256 { |
2257 if ((*fn)(e, arg)) | 2257 if ((*fn)(e, arg)) |
2258 { | 2258 { |
2278 extent_list_delete_marker (el, posm); | 2278 extent_list_delete_marker (el, posm); |
2279 } | 2279 } |
2280 } | 2280 } |
2281 | 2281 |
2282 void | 2282 void |
2283 map_extents (Bufpos from, Bufpos to, map_extents_fun fn, | 2283 map_extents (Charbpos from, Charbpos to, map_extents_fun fn, |
2284 void *arg, Lisp_Object obj, EXTENT after, unsigned int flags) | 2284 void *arg, Lisp_Object obj, EXTENT after, unsigned int flags) |
2285 { | 2285 { |
2286 map_extents_bytind (buffer_or_string_bufpos_to_bytind (obj, from), | 2286 map_extents_bytebpos (buffer_or_string_charbpos_to_bytebpos (obj, from), |
2287 buffer_or_string_bufpos_to_bytind (obj, to), fn, arg, | 2287 buffer_or_string_charbpos_to_bytebpos (obj, to), fn, arg, |
2288 obj, after, flags); | 2288 obj, after, flags); |
2289 } | 2289 } |
2290 | 2290 |
2291 /* ------------------------------- */ | 2291 /* ------------------------------- */ |
2292 /* adjust_extents() */ | 2292 /* adjust_extents() */ |
2307 around with extent endpoints without detaching and reattaching | 2307 around with extent endpoints without detaching and reattaching |
2308 the extents (this is provably correct and saves lots of time), | 2308 the extents (this is provably correct and saves lots of time), |
2309 so for safety we make it just look at the extent lists directly. */ | 2309 so for safety we make it just look at the extent lists directly. */ |
2310 | 2310 |
2311 void | 2311 void |
2312 adjust_extents (Lisp_Object obj, Memind from, Memind to, int amount) | 2312 adjust_extents (Lisp_Object obj, Membpos from, Membpos to, int amount) |
2313 { | 2313 { |
2314 int endp; | 2314 int endp; |
2315 int pos; | 2315 int pos; |
2316 int startpos[2]; | 2316 int startpos[2]; |
2317 Extent_List *el; | 2317 Extent_List *el; |
2383 There is no string correspondent for this because you can't | 2383 There is no string correspondent for this because you can't |
2384 delete characters from a string. | 2384 delete characters from a string. |
2385 */ | 2385 */ |
2386 | 2386 |
2387 void | 2387 void |
2388 adjust_extents_for_deletion (Lisp_Object object, Bytind from, | 2388 adjust_extents_for_deletion (Lisp_Object object, Bytebpos from, |
2389 Bytind to, int gapsize, int numdel, | 2389 Bytebpos to, int gapsize, int numdel, |
2390 int movegapsize) | 2390 int movegapsize) |
2391 { | 2391 { |
2392 struct adjust_extents_for_deletion_arg closure; | 2392 struct adjust_extents_for_deletion_arg closure; |
2393 int i; | 2393 int i; |
2394 Memind adjust_to = (Memind) (to + gapsize); | 2394 Membpos adjust_to = (Membpos) (to + gapsize); |
2395 Bytecount amount = - numdel - movegapsize; | 2395 Bytecount amount = - numdel - movegapsize; |
2396 Memind oldsoe = 0, newsoe = 0; | 2396 Membpos oldsoe = 0, newsoe = 0; |
2397 Stack_Of_Extents *soe = buffer_or_string_stack_of_extents (object); | 2397 Stack_Of_Extents *soe = buffer_or_string_stack_of_extents (object); |
2398 | 2398 |
2399 #ifdef ERROR_CHECK_EXTENTS | 2399 #ifdef ERROR_CHECK_EXTENTS |
2400 sledgehammer_extent_check (object); | 2400 sledgehammer_extent_check (object); |
2401 #endif | 2401 #endif |
2404 /* We're going to be playing weird games below with extents and the SOE | 2404 /* We're going to be playing weird games below with extents and the SOE |
2405 and such, so compute the list now of all the extents that we're going | 2405 and such, so compute the list now of all the extents that we're going |
2406 to muck with. If we do the mapping and adjusting together, things can | 2406 to muck with. If we do the mapping and adjusting together, things can |
2407 get all screwed up. */ | 2407 get all screwed up. */ |
2408 | 2408 |
2409 map_extents_bytind (from, to, adjust_extents_for_deletion_mapper, | 2409 map_extents_bytebpos (from, to, adjust_extents_for_deletion_mapper, |
2410 (void *) &closure, object, 0, | 2410 (void *) &closure, object, 0, |
2411 /* extent endpoints move like markers regardless | 2411 /* extent endpoints move like markers regardless |
2412 of their open/closeness. */ | 2412 of their open/closeness. */ |
2413 ME_ALL_EXTENTS_CLOSED | ME_END_CLOSED | | 2413 ME_ALL_EXTENTS_CLOSED | ME_END_CLOSED | |
2414 ME_START_OR_END_IN_REGION | ME_INCLUDE_INTERNAL); | 2414 ME_START_OR_END_IN_REGION | ME_INCLUDE_INTERNAL); |
2430 } | 2430 } |
2431 | 2431 |
2432 for (i = 0; i < Dynarr_length (closure.list); i++) | 2432 for (i = 0; i < Dynarr_length (closure.list); i++) |
2433 { | 2433 { |
2434 EXTENT extent = Dynarr_at (closure.list, i); | 2434 EXTENT extent = Dynarr_at (closure.list, i); |
2435 Memind new_start = extent_start (extent); | 2435 Membpos new_start = extent_start (extent); |
2436 Memind new_end = extent_end (extent); | 2436 Membpos new_end = extent_end (extent); |
2437 | 2437 |
2438 /* do_marker_adjustment() will not adjust values that should not be | 2438 /* do_marker_adjustment() will not adjust values that should not be |
2439 adjusted. We're passing the same funky arguments to | 2439 adjusted. We're passing the same funky arguments to |
2440 do_marker_adjustment() as buffer_delete_range() does. */ | 2440 do_marker_adjustment() as buffer_delete_range() does. */ |
2441 new_start = | 2441 new_start = |
2511 | 2511 |
2512 /* This function returns the position of the beginning of | 2512 /* This function returns the position of the beginning of |
2513 the first run that begins after POS, or returns POS if | 2513 the first run that begins after POS, or returns POS if |
2514 there are no such runs. */ | 2514 there are no such runs. */ |
2515 | 2515 |
2516 static Bytind | 2516 static Bytebpos |
2517 extent_find_end_of_run (Lisp_Object obj, Bytind pos, int outside_accessible) | 2517 extent_find_end_of_run (Lisp_Object obj, Bytebpos pos, int outside_accessible) |
2518 { | 2518 { |
2519 Extent_List *sel; | 2519 Extent_List *sel; |
2520 Extent_List *bel = buffer_or_string_extent_list (obj); | 2520 Extent_List *bel = buffer_or_string_extent_list (obj); |
2521 Bytind pos1, pos2; | 2521 Bytebpos pos1, pos2; |
2522 int elind1, elind2; | 2522 int elind1, elind2; |
2523 Memind mempos = buffer_or_string_bytind_to_memind (obj, pos); | 2523 Membpos mempos = buffer_or_string_bytebpos_to_membpos (obj, pos); |
2524 Bytind limit = outside_accessible ? | 2524 Bytebpos limit = outside_accessible ? |
2525 buffer_or_string_absolute_end_byte (obj) : | 2525 buffer_or_string_absolute_end_byte (obj) : |
2526 buffer_or_string_accessible_end_byte (obj); | 2526 buffer_or_string_accessible_end_byte (obj); |
2527 | 2527 |
2528 if (!bel || !extent_list_num_els(bel)) | 2528 if (!bel || !extent_list_num_els(bel)) |
2529 return limit; | 2529 return limit; |
2532 soe_move (obj, mempos); | 2532 soe_move (obj, mempos); |
2533 | 2533 |
2534 /* Find the first start position after POS. */ | 2534 /* Find the first start position after POS. */ |
2535 elind1 = extent_list_locate_from_pos (bel, mempos+1, 0); | 2535 elind1 = extent_list_locate_from_pos (bel, mempos+1, 0); |
2536 if (elind1 < extent_list_num_els (bel)) | 2536 if (elind1 < extent_list_num_els (bel)) |
2537 pos1 = buffer_or_string_memind_to_bytind | 2537 pos1 = buffer_or_string_membpos_to_bytebpos |
2538 (obj, extent_start (extent_list_at (bel, elind1, 0))); | 2538 (obj, extent_start (extent_list_at (bel, elind1, 0))); |
2539 else | 2539 else |
2540 pos1 = limit; | 2540 pos1 = limit; |
2541 | 2541 |
2542 /* Find the first end position after POS. The extent corresponding | 2542 /* Find the first end position after POS. The extent corresponding |
2543 to this position is either in the SOE or is greater than or | 2543 to this position is either in the SOE or is greater than or |
2544 equal to POS1, so we just have to look in the SOE. */ | 2544 equal to POS1, so we just have to look in the SOE. */ |
2545 elind2 = extent_list_locate_from_pos (sel, mempos+1, 1); | 2545 elind2 = extent_list_locate_from_pos (sel, mempos+1, 1); |
2546 if (elind2 < extent_list_num_els (sel)) | 2546 if (elind2 < extent_list_num_els (sel)) |
2547 pos2 = buffer_or_string_memind_to_bytind | 2547 pos2 = buffer_or_string_membpos_to_bytebpos |
2548 (obj, extent_end (extent_list_at (sel, elind2, 1))); | 2548 (obj, extent_end (extent_list_at (sel, elind2, 1))); |
2549 else | 2549 else |
2550 pos2 = limit; | 2550 pos2 = limit; |
2551 | 2551 |
2552 return min (min (pos1, pos2), limit); | 2552 return min (min (pos1, pos2), limit); |
2553 } | 2553 } |
2554 | 2554 |
2555 static Bytind | 2555 static Bytebpos |
2556 extent_find_beginning_of_run (Lisp_Object obj, Bytind pos, | 2556 extent_find_beginning_of_run (Lisp_Object obj, Bytebpos pos, |
2557 int outside_accessible) | 2557 int outside_accessible) |
2558 { | 2558 { |
2559 Extent_List *sel; | 2559 Extent_List *sel; |
2560 Extent_List *bel = buffer_or_string_extent_list (obj); | 2560 Extent_List *bel = buffer_or_string_extent_list (obj); |
2561 Bytind pos1, pos2; | 2561 Bytebpos pos1, pos2; |
2562 int elind1, elind2; | 2562 int elind1, elind2; |
2563 Memind mempos = buffer_or_string_bytind_to_memind (obj, pos); | 2563 Membpos mempos = buffer_or_string_bytebpos_to_membpos (obj, pos); |
2564 Bytind limit = outside_accessible ? | 2564 Bytebpos limit = outside_accessible ? |
2565 buffer_or_string_absolute_begin_byte (obj) : | 2565 buffer_or_string_absolute_begin_byte (obj) : |
2566 buffer_or_string_accessible_begin_byte (obj); | 2566 buffer_or_string_accessible_begin_byte (obj); |
2567 | 2567 |
2568 if (!bel || !extent_list_num_els(bel)) | 2568 if (!bel || !extent_list_num_els(bel)) |
2569 return limit; | 2569 return limit; |
2572 soe_move (obj, mempos); | 2572 soe_move (obj, mempos); |
2573 | 2573 |
2574 /* Find the first end position before POS. */ | 2574 /* Find the first end position before POS. */ |
2575 elind1 = extent_list_locate_from_pos (bel, mempos, 1); | 2575 elind1 = extent_list_locate_from_pos (bel, mempos, 1); |
2576 if (elind1 > 0) | 2576 if (elind1 > 0) |
2577 pos1 = buffer_or_string_memind_to_bytind | 2577 pos1 = buffer_or_string_membpos_to_bytebpos |
2578 (obj, extent_end (extent_list_at (bel, elind1 - 1, 1))); | 2578 (obj, extent_end (extent_list_at (bel, elind1 - 1, 1))); |
2579 else | 2579 else |
2580 pos1 = limit; | 2580 pos1 = limit; |
2581 | 2581 |
2582 /* Find the first start position before POS. The extent corresponding | 2582 /* Find the first start position before POS. The extent corresponding |
2583 to this position is either in the SOE or is less than or | 2583 to this position is either in the SOE or is less than or |
2584 equal to POS1, so we just have to look in the SOE. */ | 2584 equal to POS1, so we just have to look in the SOE. */ |
2585 elind2 = extent_list_locate_from_pos (sel, mempos, 0); | 2585 elind2 = extent_list_locate_from_pos (sel, mempos, 0); |
2586 if (elind2 > 0) | 2586 if (elind2 > 0) |
2587 pos2 = buffer_or_string_memind_to_bytind | 2587 pos2 = buffer_or_string_membpos_to_bytebpos |
2588 (obj, extent_start (extent_list_at (sel, elind2 - 1, 0))); | 2588 (obj, extent_start (extent_list_at (sel, elind2 - 1, 0))); |
2589 else | 2589 else |
2590 pos2 = limit; | 2590 pos2 = limit; |
2591 | 2591 |
2592 return max (max (pos1, pos2), limit); | 2592 return max (max (pos1, pos2), limit); |
2751 return 0; | 2751 return 0; |
2752 } | 2752 } |
2753 | 2753 |
2754 face_index | 2754 face_index |
2755 extent_fragment_update (struct window *w, struct extent_fragment *ef, | 2755 extent_fragment_update (struct window *w, struct extent_fragment *ef, |
2756 Bytind pos) | 2756 Bytebpos pos) |
2757 { | 2757 { |
2758 int i; | 2758 int i; |
2759 Extent_List *sel = | 2759 Extent_List *sel = |
2760 buffer_or_string_stack_of_extents_force (ef->object)->extents; | 2760 buffer_or_string_stack_of_extents_force (ef->object)->extents; |
2761 EXTENT lhe = 0; | 2761 EXTENT lhe = 0; |
2762 struct extent dummy_lhe_extent; | 2762 struct extent dummy_lhe_extent; |
2763 Memind mempos = buffer_or_string_bytind_to_memind (ef->object, pos); | 2763 Membpos mempos = buffer_or_string_bytebpos_to_membpos (ef->object, pos); |
2764 | 2764 |
2765 #ifdef ERROR_CHECK_EXTENTS | 2765 #ifdef ERROR_CHECK_EXTENTS |
2766 assert (pos >= buffer_or_string_accessible_begin_byte (ef->object) | 2766 assert (pos >= buffer_or_string_accessible_begin_byte (ef->object) |
2767 && pos <= buffer_or_string_accessible_end_byte (ef->object)); | 2767 && pos <= buffer_or_string_accessible_end_byte (ef->object)); |
2768 #endif | 2768 #endif |
3102 internal_equal (extent_object (e1), extent_object (e2), depth + 1) && | 3102 internal_equal (extent_object (e1), extent_object (e2), depth + 1) && |
3103 properties_equal (extent_ancestor (e1), extent_ancestor (e2), | 3103 properties_equal (extent_ancestor (e1), extent_ancestor (e2), |
3104 depth)); | 3104 depth)); |
3105 } | 3105 } |
3106 | 3106 |
3107 static Hash_Code | 3107 static Hashcode |
3108 extent_hash (Lisp_Object obj, int depth) | 3108 extent_hash (Lisp_Object obj, int depth) |
3109 { | 3109 { |
3110 struct extent *e = XEXTENT (obj); | 3110 struct extent *e = XEXTENT (obj); |
3111 /* No need to hash all of the elements; that would take too long. | 3111 /* No need to hash all of the elements; that would take too long. |
3112 Just hash the most common ones. */ | 3112 Just hash the most common ones. */ |
3260 EXTENT extent = decode_extent (extent_obj, 0); | 3260 EXTENT extent = decode_extent (extent_obj, 0); |
3261 | 3261 |
3262 if (extent_detached_p (extent)) | 3262 if (extent_detached_p (extent)) |
3263 return Qnil; | 3263 return Qnil; |
3264 else | 3264 else |
3265 return make_int (extent_endpoint_bufpos (extent, endp)); | 3265 return make_int (extent_endpoint_charbpos (extent, endp)); |
3266 } | 3266 } |
3267 | 3267 |
3268 DEFUN ("extentp", Fextentp, 1, 1, 0, /* | 3268 DEFUN ("extentp", Fextentp, 1, 1, 0, /* |
3269 Return t if OBJECT is an extent. | 3269 Return t if OBJECT is an extent. |
3270 */ | 3270 */ |
3317 Return length of EXTENT in characters. | 3317 Return length of EXTENT in characters. |
3318 */ | 3318 */ |
3319 (extent)) | 3319 (extent)) |
3320 { | 3320 { |
3321 EXTENT e = decode_extent (extent, DE_MUST_BE_ATTACHED); | 3321 EXTENT e = decode_extent (extent, DE_MUST_BE_ATTACHED); |
3322 return make_int (extent_endpoint_bufpos (e, 1) | 3322 return make_int (extent_endpoint_charbpos (e, 1) |
3323 - extent_endpoint_bufpos (e, 0)); | 3323 - extent_endpoint_charbpos (e, 0)); |
3324 } | 3324 } |
3325 | 3325 |
3326 DEFUN ("next-extent", Fnext_extent, 1, 1, 0, /* | 3326 DEFUN ("next-extent", Fnext_extent, 1, 1, 0, /* |
3327 Find next extent after EXTENT. | 3327 Find next extent after EXTENT. |
3328 If EXTENT is a buffer return the first extent in the buffer; likewise | 3328 If EXTENT is a buffer return the first extent in the buffer; likewise |
3429 If OBJECT is nil, the current buffer is assumed. | 3429 If OBJECT is nil, the current buffer is assumed. |
3430 */ | 3430 */ |
3431 (pos, object)) | 3431 (pos, object)) |
3432 { | 3432 { |
3433 Lisp_Object obj = decode_buffer_or_string (object); | 3433 Lisp_Object obj = decode_buffer_or_string (object); |
3434 Bytind bpos; | 3434 Bytebpos bpos; |
3435 | 3435 |
3436 bpos = get_buffer_or_string_pos_byte (obj, pos, GB_ALLOW_PAST_ACCESSIBLE); | 3436 bpos = get_buffer_or_string_pos_byte (obj, pos, GB_ALLOW_PAST_ACCESSIBLE); |
3437 bpos = extent_find_end_of_run (obj, bpos, 1); | 3437 bpos = extent_find_end_of_run (obj, bpos, 1); |
3438 return make_int (buffer_or_string_bytind_to_bufpos (obj, bpos)); | 3438 return make_int (buffer_or_string_bytebpos_to_charbpos (obj, bpos)); |
3439 } | 3439 } |
3440 | 3440 |
3441 DEFUN ("previous-extent-change", Fprevious_extent_change, 1, 2, 0, /* | 3441 DEFUN ("previous-extent-change", Fprevious_extent_change, 1, 2, 0, /* |
3442 Return the last position before POS where an extent begins or ends. | 3442 Return the last position before POS where an extent begins or ends. |
3443 If POS is at the beginning of the buffer or string, POS will be returned; | 3443 If POS is at the beginning of the buffer or string, POS will be returned; |
3445 If OBJECT is nil, the current buffer is assumed. | 3445 If OBJECT is nil, the current buffer is assumed. |
3446 */ | 3446 */ |
3447 (pos, object)) | 3447 (pos, object)) |
3448 { | 3448 { |
3449 Lisp_Object obj = decode_buffer_or_string (object); | 3449 Lisp_Object obj = decode_buffer_or_string (object); |
3450 Bytind bpos; | 3450 Bytebpos bpos; |
3451 | 3451 |
3452 bpos = get_buffer_or_string_pos_byte (obj, pos, GB_ALLOW_PAST_ACCESSIBLE); | 3452 bpos = get_buffer_or_string_pos_byte (obj, pos, GB_ALLOW_PAST_ACCESSIBLE); |
3453 bpos = extent_find_beginning_of_run (obj, bpos, 1); | 3453 bpos = extent_find_beginning_of_run (obj, bpos, 1); |
3454 return make_int (buffer_or_string_bytind_to_bufpos (obj, bpos)); | 3454 return make_int (buffer_or_string_bytebpos_to_charbpos (obj, bpos)); |
3455 } | 3455 } |
3456 | 3456 |
3457 | 3457 |
3458 /************************************************************************/ | 3458 /************************************************************************/ |
3459 /* parent and children stuff */ | 3459 /* parent and children stuff */ |
3573 undo records for transient extents via update-extent. | 3573 undo records for transient extents via update-extent. |
3574 For example, query-replace will do this. | 3574 For example, query-replace will do this. |
3575 */ | 3575 */ |
3576 | 3576 |
3577 static void | 3577 static void |
3578 set_extent_endpoints_1 (EXTENT extent, Memind start, Memind end) | 3578 set_extent_endpoints_1 (EXTENT extent, Membpos start, Membpos end) |
3579 { | 3579 { |
3580 #ifdef ERROR_CHECK_EXTENTS | 3580 #ifdef ERROR_CHECK_EXTENTS |
3581 Lisp_Object obj = extent_object (extent); | 3581 Lisp_Object obj = extent_object (extent); |
3582 | 3582 |
3583 assert (start <= end); | 3583 assert (start <= end); |
3584 if (BUFFERP (obj)) | 3584 if (BUFFERP (obj)) |
3585 { | 3585 { |
3586 assert (valid_memind_p (XBUFFER (obj), start)); | 3586 assert (valid_membpos_p (XBUFFER (obj), start)); |
3587 assert (valid_memind_p (XBUFFER (obj), end)); | 3587 assert (valid_membpos_p (XBUFFER (obj), end)); |
3588 } | 3588 } |
3589 #endif | 3589 #endif |
3590 | 3590 |
3591 /* Optimization: if the extent is already where we want it to be, | 3591 /* Optimization: if the extent is already where we want it to be, |
3592 do nothing. */ | 3592 do nothing. */ |
3613 | 3613 |
3614 /* Set extent's endpoints to S and E, and put extent in buffer or string | 3614 /* Set extent's endpoints to S and E, and put extent in buffer or string |
3615 OBJECT. (If OBJECT is nil, do not change the extent's object.) */ | 3615 OBJECT. (If OBJECT is nil, do not change the extent's object.) */ |
3616 | 3616 |
3617 void | 3617 void |
3618 set_extent_endpoints (EXTENT extent, Bytind s, Bytind e, Lisp_Object object) | 3618 set_extent_endpoints (EXTENT extent, Bytebpos s, Bytebpos e, Lisp_Object object) |
3619 { | 3619 { |
3620 Memind start, end; | 3620 Membpos start, end; |
3621 | 3621 |
3622 if (NILP (object)) | 3622 if (NILP (object)) |
3623 { | 3623 { |
3624 object = extent_object (extent); | 3624 object = extent_object (extent); |
3625 assert (!NILP (object)); | 3625 assert (!NILP (object)); |
3629 extent_detach (extent); | 3629 extent_detach (extent); |
3630 extent_object (extent) = object; | 3630 extent_object (extent) = object; |
3631 } | 3631 } |
3632 | 3632 |
3633 start = s < 0 ? extent_start (extent) : | 3633 start = s < 0 ? extent_start (extent) : |
3634 buffer_or_string_bytind_to_memind (object, s); | 3634 buffer_or_string_bytebpos_to_membpos (object, s); |
3635 end = e < 0 ? extent_end (extent) : | 3635 end = e < 0 ? extent_end (extent) : |
3636 buffer_or_string_bytind_to_memind (object, e); | 3636 buffer_or_string_bytebpos_to_membpos (object, e); |
3637 set_extent_endpoints_1 (extent, start, end); | 3637 set_extent_endpoints_1 (extent, start, end); |
3638 } | 3638 } |
3639 | 3639 |
3640 static void | 3640 static void |
3641 set_extent_openness (EXTENT extent, int start_open, int end_open) | 3641 set_extent_openness (EXTENT extent, int start_open, int end_open) |
3647 /* changing the open/closedness of an extent does not affect | 3647 /* changing the open/closedness of an extent does not affect |
3648 redisplay. */ | 3648 redisplay. */ |
3649 } | 3649 } |
3650 | 3650 |
3651 static EXTENT | 3651 static EXTENT |
3652 make_extent_internal (Lisp_Object object, Bytind from, Bytind to) | 3652 make_extent_internal (Lisp_Object object, Bytebpos from, Bytebpos to) |
3653 { | 3653 { |
3654 EXTENT extent; | 3654 EXTENT extent; |
3655 | 3655 |
3656 extent = make_extent_detached (object); | 3656 extent = make_extent_detached (object); |
3657 set_extent_endpoints (extent, from, to, Qnil); | 3657 set_extent_endpoints (extent, from, to, Qnil); |
3658 return extent; | 3658 return extent; |
3659 } | 3659 } |
3660 | 3660 |
3661 static EXTENT | 3661 static EXTENT |
3662 copy_extent (EXTENT original, Bytind from, Bytind to, Lisp_Object object) | 3662 copy_extent (EXTENT original, Bytebpos from, Bytebpos to, Lisp_Object object) |
3663 { | 3663 { |
3664 EXTENT e; | 3664 EXTENT e; |
3665 | 3665 |
3666 e = make_extent_detached (object); | 3666 e = make_extent_detached (object); |
3667 if (from >= 0) | 3667 if (from >= 0) |
3739 obj = Qnil; | 3739 obj = Qnil; |
3740 XSETEXTENT (extent_obj, make_extent_detached (obj)); | 3740 XSETEXTENT (extent_obj, make_extent_detached (obj)); |
3741 } | 3741 } |
3742 else | 3742 else |
3743 { | 3743 { |
3744 Bytind start, end; | 3744 Bytebpos start, end; |
3745 | 3745 |
3746 get_buffer_or_string_range_byte (obj, from, to, &start, &end, | 3746 get_buffer_or_string_range_byte (obj, from, to, &start, &end, |
3747 GB_ALLOW_PAST_ACCESSIBLE); | 3747 GB_ALLOW_PAST_ACCESSIBLE); |
3748 XSETEXTENT (extent_obj, make_extent_internal (obj, start, end)); | 3748 XSETEXTENT (extent_obj, make_extent_internal (obj, start, end)); |
3749 } | 3749 } |
3822 See documentation on `detach-extent' for a discussion of undo recording. | 3822 See documentation on `detach-extent' for a discussion of undo recording. |
3823 */ | 3823 */ |
3824 (extent, start, end, buffer_or_string)) | 3824 (extent, start, end, buffer_or_string)) |
3825 { | 3825 { |
3826 EXTENT ext; | 3826 EXTENT ext; |
3827 Bytind s, e; | 3827 Bytebpos s, e; |
3828 | 3828 |
3829 ext = decode_extent (extent, 0); | 3829 ext = decode_extent (extent, 0); |
3830 | 3830 |
3831 if (NILP (buffer_or_string)) | 3831 if (NILP (buffer_or_string)) |
3832 { | 3832 { |
3914 This is equivalent to whether `map-extents' would visit EXTENT when called | 3914 This is equivalent to whether `map-extents' would visit EXTENT when called |
3915 with these args. | 3915 with these args. |
3916 */ | 3916 */ |
3917 (extent, from, to, flags)) | 3917 (extent, from, to, flags)) |
3918 { | 3918 { |
3919 Bytind start, end; | 3919 Bytebpos start, end; |
3920 EXTENT ext = decode_extent (extent, DE_MUST_BE_ATTACHED); | 3920 EXTENT ext = decode_extent (extent, DE_MUST_BE_ATTACHED); |
3921 Lisp_Object obj = extent_object (ext); | 3921 Lisp_Object obj = extent_object (ext); |
3922 | 3922 |
3923 get_buffer_or_string_range_byte (obj, from, to, &start, &end, GB_ALLOW_NIL | | 3923 get_buffer_or_string_range_byte (obj, from, to, &start, &end, GB_ALLOW_NIL | |
3924 GB_ALLOW_PAST_ACCESSIBLE); | 3924 GB_ALLOW_PAST_ACCESSIBLE); |
4038 (function, object, from, to, maparg, flags, property, value)) | 4038 (function, object, from, to, maparg, flags, property, value)) |
4039 { | 4039 { |
4040 /* This function can GC */ | 4040 /* This function can GC */ |
4041 struct slow_map_extents_arg closure; | 4041 struct slow_map_extents_arg closure; |
4042 unsigned int me_flags; | 4042 unsigned int me_flags; |
4043 Bytind start, end; | 4043 Bytebpos start, end; |
4044 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 4044 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
4045 EXTENT after = 0; | 4045 EXTENT after = 0; |
4046 | 4046 |
4047 if (EXTENTP (object)) | 4047 if (EXTENTP (object)) |
4048 { | 4048 { |
4073 closure.map_routine = function; | 4073 closure.map_routine = function; |
4074 closure.result = Qnil; | 4074 closure.result = Qnil; |
4075 closure.property = property; | 4075 closure.property = property; |
4076 closure.value = value; | 4076 closure.value = value; |
4077 | 4077 |
4078 map_extents_bytind (start, end, slow_map_extents_function, | 4078 map_extents_bytebpos (start, end, slow_map_extents_function, |
4079 (void *) &closure, object, after, | 4079 (void *) &closure, object, after, |
4080 /* You never know what the user might do ... */ | 4080 /* You never know what the user might do ... */ |
4081 me_flags | ME_MIGHT_CALL_ELISP); | 4081 me_flags | ME_MIGHT_CALL_ELISP); |
4082 | 4082 |
4083 UNGCPRO; | 4083 UNGCPRO; |
4098 Lisp_Object map_arg; | 4098 Lisp_Object map_arg; |
4099 Lisp_Object map_routine; | 4099 Lisp_Object map_routine; |
4100 Lisp_Object result; | 4100 Lisp_Object result; |
4101 Lisp_Object property; | 4101 Lisp_Object property; |
4102 Lisp_Object value; | 4102 Lisp_Object value; |
4103 Bytind start_min; | 4103 Bytebpos start_min; |
4104 Bytind prev_start; | 4104 Bytebpos prev_start; |
4105 Bytind prev_end; | 4105 Bytebpos prev_end; |
4106 }; | 4106 }; |
4107 | 4107 |
4108 static int | 4108 static int |
4109 slow_map_extent_children_function (EXTENT extent, void *arg) | 4109 slow_map_extent_children_function (EXTENT extent, void *arg) |
4110 { | 4110 { |
4111 /* This function can GC */ | 4111 /* This function can GC */ |
4112 struct slow_map_extent_children_arg *closure = | 4112 struct slow_map_extent_children_arg *closure = |
4113 (struct slow_map_extent_children_arg *) arg; | 4113 (struct slow_map_extent_children_arg *) arg; |
4114 Lisp_Object extent_obj; | 4114 Lisp_Object extent_obj; |
4115 Bytind start = extent_endpoint_bytind (extent, 0); | 4115 Bytebpos start = extent_endpoint_bytebpos (extent, 0); |
4116 Bytind end = extent_endpoint_bytind (extent, 1); | 4116 Bytebpos end = extent_endpoint_bytebpos (extent, 1); |
4117 /* Make sure the extent starts inside the region of interest, | 4117 /* Make sure the extent starts inside the region of interest, |
4118 rather than just overlaps it. | 4118 rather than just overlaps it. |
4119 */ | 4119 */ |
4120 if (start < closure->start_min) | 4120 if (start < closure->start_min) |
4121 return 0; | 4121 return 0; |
4154 | 4154 |
4155 /* Since the callback may change the buffer, compute all stored | 4155 /* Since the callback may change the buffer, compute all stored |
4156 buffer positions here. | 4156 buffer positions here. |
4157 */ | 4157 */ |
4158 closure->start_min = -1; /* no need for this any more */ | 4158 closure->start_min = -1; /* no need for this any more */ |
4159 closure->prev_start = extent_endpoint_bytind (extent, 0); | 4159 closure->prev_start = extent_endpoint_bytebpos (extent, 0); |
4160 closure->prev_end = extent_endpoint_bytind (extent, 1); | 4160 closure->prev_end = extent_endpoint_bytebpos (extent, 1); |
4161 | 4161 |
4162 return !NILP (closure->result); | 4162 return !NILP (closure->result); |
4163 } | 4163 } |
4164 | 4164 |
4165 DEFUN ("map-extent-children", Fmap_extent_children, 1, 8, 0, /* | 4165 DEFUN ("map-extent-children", Fmap_extent_children, 1, 8, 0, /* |
4179 (function, object, from, to, maparg, flags, property, value)) | 4179 (function, object, from, to, maparg, flags, property, value)) |
4180 { | 4180 { |
4181 /* This function can GC */ | 4181 /* This function can GC */ |
4182 struct slow_map_extent_children_arg closure; | 4182 struct slow_map_extent_children_arg closure; |
4183 unsigned int me_flags; | 4183 unsigned int me_flags; |
4184 Bytind start, end; | 4184 Bytebpos start, end; |
4185 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 4185 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
4186 EXTENT after = 0; | 4186 EXTENT after = 0; |
4187 | 4187 |
4188 if (EXTENTP (object)) | 4188 if (EXTENTP (object)) |
4189 { | 4189 { |
4216 closure.property = property; | 4216 closure.property = property; |
4217 closure.value = value; | 4217 closure.value = value; |
4218 closure.start_min = start; | 4218 closure.start_min = start; |
4219 closure.prev_start = -1; | 4219 closure.prev_start = -1; |
4220 closure.prev_end = -1; | 4220 closure.prev_end = -1; |
4221 map_extents_bytind (start, end, slow_map_extent_children_function, | 4221 map_extents_bytebpos (start, end, slow_map_extent_children_function, |
4222 (void *) &closure, object, after, | 4222 (void *) &closure, object, after, |
4223 /* You never know what the user might do ... */ | 4223 /* You never know what the user might do ... */ |
4224 me_flags | ME_MIGHT_CALL_ELISP); | 4224 me_flags | ME_MIGHT_CALL_ELISP); |
4225 | 4225 |
4226 UNGCPRO; | 4226 UNGCPRO; |
4239 */ | 4239 */ |
4240 | 4240 |
4241 struct extent_at_arg | 4241 struct extent_at_arg |
4242 { | 4242 { |
4243 Lisp_Object best_match; /* or list of extents */ | 4243 Lisp_Object best_match; /* or list of extents */ |
4244 Memind best_start; | 4244 Membpos best_start; |
4245 Memind best_end; | 4245 Membpos best_end; |
4246 Lisp_Object prop; | 4246 Lisp_Object prop; |
4247 EXTENT before; | 4247 EXTENT before; |
4248 int all_extents; | 4248 int all_extents; |
4249 }; | 4249 }; |
4250 | 4250 |
4323 | 4323 |
4324 return 0; | 4324 return 0; |
4325 } | 4325 } |
4326 | 4326 |
4327 static Lisp_Object | 4327 static Lisp_Object |
4328 extent_at_bytind (Bytind position, Lisp_Object object, Lisp_Object property, | 4328 extent_at_bytebpos (Bytebpos position, Lisp_Object object, Lisp_Object property, |
4329 EXTENT before, enum extent_at_flag at_flag, int all_extents) | 4329 EXTENT before, enum extent_at_flag at_flag, int all_extents) |
4330 { | 4330 { |
4331 struct extent_at_arg closure; | 4331 struct extent_at_arg closure; |
4332 struct gcpro gcpro1; | 4332 struct gcpro gcpro1; |
4333 | 4333 |
4351 closure.prop = property; | 4351 closure.prop = property; |
4352 closure.before = before; | 4352 closure.before = before; |
4353 closure.all_extents = all_extents; | 4353 closure.all_extents = all_extents; |
4354 | 4354 |
4355 GCPRO1 (closure.best_match); | 4355 GCPRO1 (closure.best_match); |
4356 map_extents_bytind (at_flag == EXTENT_AT_BEFORE ? position - 1 : position, | 4356 map_extents_bytebpos (at_flag == EXTENT_AT_BEFORE ? position - 1 : position, |
4357 at_flag == EXTENT_AT_AFTER ? position + 1 : position, | 4357 at_flag == EXTENT_AT_AFTER ? position + 1 : position, |
4358 extent_at_mapper, (void *) &closure, object, 0, | 4358 extent_at_mapper, (void *) &closure, object, 0, |
4359 ME_START_OPEN | ME_ALL_EXTENTS_CLOSED); | 4359 ME_START_OPEN | ME_ALL_EXTENTS_CLOSED); |
4360 if (all_extents) | 4360 if (all_extents) |
4361 closure.best_match = Fnreverse (closure.best_match); | 4361 closure.best_match = Fnreverse (closure.best_match); |
4392 considered is ignored. If you want to pay attention to those properties, | 4392 considered is ignored. If you want to pay attention to those properties, |
4393 you should use `map-extents', which gives you more control. | 4393 you should use `map-extents', which gives you more control. |
4394 */ | 4394 */ |
4395 (pos, object, property, before, at_flag)) | 4395 (pos, object, property, before, at_flag)) |
4396 { | 4396 { |
4397 Bytind position; | 4397 Bytebpos position; |
4398 EXTENT before_extent; | 4398 EXTENT before_extent; |
4399 enum extent_at_flag fl; | 4399 enum extent_at_flag fl; |
4400 | 4400 |
4401 object = decode_buffer_or_string (object); | 4401 object = decode_buffer_or_string (object); |
4402 position = get_buffer_or_string_pos_byte (object, pos, GB_NO_ERROR_IF_BAD); | 4402 position = get_buffer_or_string_pos_byte (object, pos, GB_NO_ERROR_IF_BAD); |
4406 before_extent = decode_extent (before, DE_MUST_BE_ATTACHED); | 4406 before_extent = decode_extent (before, DE_MUST_BE_ATTACHED); |
4407 if (before_extent && !EQ (object, extent_object (before_extent))) | 4407 if (before_extent && !EQ (object, extent_object (before_extent))) |
4408 invalid_argument ("extent not in specified buffer or string", object); | 4408 invalid_argument ("extent not in specified buffer or string", object); |
4409 fl = decode_extent_at_flag (at_flag); | 4409 fl = decode_extent_at_flag (at_flag); |
4410 | 4410 |
4411 return extent_at_bytind (position, object, property, before_extent, fl, 0); | 4411 return extent_at_bytebpos (position, object, property, before_extent, fl, 0); |
4412 } | 4412 } |
4413 | 4413 |
4414 DEFUN ("extents-at", Fextents_at, 1, 5, 0, /* | 4414 DEFUN ("extents-at", Fextents_at, 1, 5, 0, /* |
4415 Find all extents at POS in OBJECT having PROPERTY set. | 4415 Find all extents at POS in OBJECT having PROPERTY set. |
4416 Normally, an extent is "at" POS if it overlaps the region (POS, POS+1); | 4416 Normally, an extent is "at" POS if it overlaps the region (POS, POS+1); |
4442 considered is ignored. If you want to pay attention to those properties, | 4442 considered is ignored. If you want to pay attention to those properties, |
4443 you should use `map-extents', which gives you more control. | 4443 you should use `map-extents', which gives you more control. |
4444 */ | 4444 */ |
4445 (pos, object, property, before, at_flag)) | 4445 (pos, object, property, before, at_flag)) |
4446 { | 4446 { |
4447 Bytind position; | 4447 Bytebpos position; |
4448 EXTENT before_extent; | 4448 EXTENT before_extent; |
4449 enum extent_at_flag fl; | 4449 enum extent_at_flag fl; |
4450 | 4450 |
4451 object = decode_buffer_or_string (object); | 4451 object = decode_buffer_or_string (object); |
4452 position = get_buffer_or_string_pos_byte (object, pos, GB_NO_ERROR_IF_BAD); | 4452 position = get_buffer_or_string_pos_byte (object, pos, GB_NO_ERROR_IF_BAD); |
4456 before_extent = decode_extent (before, DE_MUST_BE_ATTACHED); | 4456 before_extent = decode_extent (before, DE_MUST_BE_ATTACHED); |
4457 if (before_extent && !EQ (object, extent_object (before_extent))) | 4457 if (before_extent && !EQ (object, extent_object (before_extent))) |
4458 invalid_argument ("extent not in specified buffer or string", object); | 4458 invalid_argument ("extent not in specified buffer or string", object); |
4459 fl = decode_extent_at_flag (at_flag); | 4459 fl = decode_extent_at_flag (at_flag); |
4460 | 4460 |
4461 return extent_at_bytind (position, object, property, before_extent, fl, 1); | 4461 return extent_at_bytebpos (position, object, property, before_extent, fl, 1); |
4462 } | 4462 } |
4463 | 4463 |
4464 /* ------------------------------- */ | 4464 /* ------------------------------- */ |
4465 /* verify_extent_modification() */ | 4465 /* verify_extent_modification() */ |
4466 /* ------------------------------- */ | 4466 /* ------------------------------- */ |
4471 */ | 4471 */ |
4472 | 4472 |
4473 struct verify_extents_arg | 4473 struct verify_extents_arg |
4474 { | 4474 { |
4475 Lisp_Object object; | 4475 Lisp_Object object; |
4476 Memind start; | 4476 Membpos start; |
4477 Memind end; | 4477 Membpos end; |
4478 Lisp_Object iro; /* value of inhibit-read-only */ | 4478 Lisp_Object iro; /* value of inhibit-read-only */ |
4479 }; | 4479 }; |
4480 | 4480 |
4481 static int | 4481 static int |
4482 verify_extent_mapper (EXTENT extent, void *arg) | 4482 verify_extent_mapper (EXTENT extent, void *arg) |
4512 | 4512 |
4513 /* Value of Vinhibit_read_only is precomputed and passed in for | 4513 /* Value of Vinhibit_read_only is precomputed and passed in for |
4514 efficiency */ | 4514 efficiency */ |
4515 | 4515 |
4516 void | 4516 void |
4517 verify_extent_modification (Lisp_Object object, Bytind from, Bytind to, | 4517 verify_extent_modification (Lisp_Object object, Bytebpos from, Bytebpos to, |
4518 Lisp_Object inhibit_read_only_value) | 4518 Lisp_Object inhibit_read_only_value) |
4519 { | 4519 { |
4520 int closed; | 4520 int closed; |
4521 struct verify_extents_arg closure; | 4521 struct verify_extents_arg closure; |
4522 | 4522 |
4527 changed range has zero length, and a deletion otherwise. This | 4527 changed range has zero length, and a deletion otherwise. This |
4528 fails if a change (i.e. non-insertion, non-deletion) is happening. | 4528 fails if a change (i.e. non-insertion, non-deletion) is happening. |
4529 As far as I know, this doesn't currently occur in XEmacs. --ben */ | 4529 As far as I know, this doesn't currently occur in XEmacs. --ben */ |
4530 closed = (from==to); | 4530 closed = (from==to); |
4531 closure.object = object; | 4531 closure.object = object; |
4532 closure.start = buffer_or_string_bytind_to_memind (object, from); | 4532 closure.start = buffer_or_string_bytebpos_to_membpos (object, from); |
4533 closure.end = buffer_or_string_bytind_to_memind (object, to); | 4533 closure.end = buffer_or_string_bytebpos_to_membpos (object, to); |
4534 closure.iro = inhibit_read_only_value; | 4534 closure.iro = inhibit_read_only_value; |
4535 | 4535 |
4536 map_extents_bytind (from, to, verify_extent_mapper, (void *) &closure, | 4536 map_extents_bytebpos (from, to, verify_extent_mapper, (void *) &closure, |
4537 object, 0, closed ? ME_END_CLOSED : ME_START_OPEN); | 4537 object, 0, closed ? ME_END_CLOSED : ME_START_OPEN); |
4538 } | 4538 } |
4539 | 4539 |
4540 /* ------------------------------------ */ | 4540 /* ------------------------------------ */ |
4541 /* process_extents_for_insertion() */ | 4541 /* process_extents_for_insertion() */ |
4542 /* ------------------------------------ */ | 4542 /* ------------------------------------ */ |
4543 | 4543 |
4544 struct process_extents_for_insertion_arg | 4544 struct process_extents_for_insertion_arg |
4545 { | 4545 { |
4546 Bytind opoint; | 4546 Bytebpos opoint; |
4547 int length; | 4547 int length; |
4548 Lisp_Object object; | 4548 Lisp_Object object; |
4549 }; | 4549 }; |
4550 | 4550 |
4551 /* A region of length LENGTH was just inserted at OPOINT. Modify all | 4551 /* A region of length LENGTH was just inserted at OPOINT. Modify all |
4556 static int | 4556 static int |
4557 process_extents_for_insertion_mapper (EXTENT extent, void *arg) | 4557 process_extents_for_insertion_mapper (EXTENT extent, void *arg) |
4558 { | 4558 { |
4559 struct process_extents_for_insertion_arg *closure = | 4559 struct process_extents_for_insertion_arg *closure = |
4560 (struct process_extents_for_insertion_arg *) arg; | 4560 (struct process_extents_for_insertion_arg *) arg; |
4561 Memind indice = buffer_or_string_bytind_to_memind (closure->object, | 4561 Membpos indice = buffer_or_string_bytebpos_to_membpos (closure->object, |
4562 closure->opoint); | 4562 closure->opoint); |
4563 | 4563 |
4564 /* When this function is called, one end of the newly-inserted text should | 4564 /* When this function is called, one end of the newly-inserted text should |
4565 be adjacent to some endpoint of the extent, or disjoint from it. If | 4565 be adjacent to some endpoint of the extent, or disjoint from it. If |
4566 the insertion overlaps any existing extent, something is wrong. | 4566 the insertion overlaps any existing extent, something is wrong. |
4592 Existence of zero-length open-open extents is unfortunately an | 4592 Existence of zero-length open-open extents is unfortunately an |
4593 inelegant part of the extent model, but there is no way around | 4593 inelegant part of the extent model, but there is no way around |
4594 it. */ | 4594 it. */ |
4595 | 4595 |
4596 { | 4596 { |
4597 Memind new_start = extent_start (extent); | 4597 Membpos new_start = extent_start (extent); |
4598 Memind new_end = extent_end (extent); | 4598 Membpos new_end = extent_end (extent); |
4599 | 4599 |
4600 if (indice == extent_start (extent) && extent_start_open_p (extent) | 4600 if (indice == extent_start (extent) && extent_start_open_p (extent) |
4601 /* zero-length () extents are exempt; see comment above. */ | 4601 /* zero-length () extents are exempt; see comment above. */ |
4602 && !(new_start == new_end && extent_end_open_p (extent)) | 4602 && !(new_start == new_end && extent_end_open_p (extent)) |
4603 ) | 4603 ) |
4610 | 4610 |
4611 return 0; | 4611 return 0; |
4612 } | 4612 } |
4613 | 4613 |
4614 void | 4614 void |
4615 process_extents_for_insertion (Lisp_Object object, Bytind opoint, | 4615 process_extents_for_insertion (Lisp_Object object, Bytebpos opoint, |
4616 Bytecount length) | 4616 Bytecount length) |
4617 { | 4617 { |
4618 struct process_extents_for_insertion_arg closure; | 4618 struct process_extents_for_insertion_arg closure; |
4619 | 4619 |
4620 closure.opoint = opoint; | 4620 closure.opoint = opoint; |
4621 closure.length = length; | 4621 closure.length = length; |
4622 closure.object = object; | 4622 closure.object = object; |
4623 | 4623 |
4624 map_extents_bytind (opoint, opoint + length, | 4624 map_extents_bytebpos (opoint, opoint + length, |
4625 process_extents_for_insertion_mapper, | 4625 process_extents_for_insertion_mapper, |
4626 (void *) &closure, object, 0, | 4626 (void *) &closure, object, 0, |
4627 ME_END_CLOSED | ME_MIGHT_MODIFY_EXTENTS | | 4627 ME_END_CLOSED | ME_MIGHT_MODIFY_EXTENTS | |
4628 ME_INCLUDE_INTERNAL); | 4628 ME_INCLUDE_INTERNAL); |
4629 } | 4629 } |
4632 /* process_extents_for_deletion() */ | 4632 /* process_extents_for_deletion() */ |
4633 /* ------------------------------------ */ | 4633 /* ------------------------------------ */ |
4634 | 4634 |
4635 struct process_extents_for_deletion_arg | 4635 struct process_extents_for_deletion_arg |
4636 { | 4636 { |
4637 Memind start, end; | 4637 Membpos start, end; |
4638 int destroy_included_extents; | 4638 int destroy_included_extents; |
4639 }; | 4639 }; |
4640 | 4640 |
4641 /* This function is called when we're about to delete the range [from, to]. | 4641 /* This function is called when we're about to delete the range [from, to]. |
4642 Detach all of the extents that are completely inside the range [from, to], | 4642 Detach all of the extents that are completely inside the range [from, to], |
4670 /* DESTROY_THEM means destroy the extents instead of just deleting them. | 4670 /* DESTROY_THEM means destroy the extents instead of just deleting them. |
4671 It is unused currently, but perhaps might be used (there used to | 4671 It is unused currently, but perhaps might be used (there used to |
4672 be a function process_extents_for_destruction(), #if 0'd out, | 4672 be a function process_extents_for_destruction(), #if 0'd out, |
4673 that did the equivalent). */ | 4673 that did the equivalent). */ |
4674 void | 4674 void |
4675 process_extents_for_deletion (Lisp_Object object, Bytind from, | 4675 process_extents_for_deletion (Lisp_Object object, Bytebpos from, |
4676 Bytind to, int destroy_them) | 4676 Bytebpos to, int destroy_them) |
4677 { | 4677 { |
4678 struct process_extents_for_deletion_arg closure; | 4678 struct process_extents_for_deletion_arg closure; |
4679 | 4679 |
4680 closure.start = buffer_or_string_bytind_to_memind (object, from); | 4680 closure.start = buffer_or_string_bytebpos_to_membpos (object, from); |
4681 closure.end = buffer_or_string_bytind_to_memind (object, to); | 4681 closure.end = buffer_or_string_bytebpos_to_membpos (object, to); |
4682 closure.destroy_included_extents = destroy_them; | 4682 closure.destroy_included_extents = destroy_them; |
4683 | 4683 |
4684 map_extents_bytind (from, to, process_extents_for_deletion_mapper, | 4684 map_extents_bytebpos (from, to, process_extents_for_deletion_mapper, |
4685 (void *) &closure, object, 0, | 4685 (void *) &closure, object, 0, |
4686 ME_END_CLOSED | ME_MIGHT_MODIFY_EXTENTS); | 4686 ME_END_CLOSED | ME_MIGHT_MODIFY_EXTENTS); |
4687 } | 4687 } |
4688 | 4688 |
4689 /* ------------------------------- */ | 4689 /* ------------------------------- */ |
4690 /* report_extent_modification() */ | 4690 /* report_extent_modification() */ |
4691 /* ------------------------------- */ | 4691 /* ------------------------------- */ |
4692 struct report_extent_modification_closure { | 4692 struct report_extent_modification_closure { |
4693 Lisp_Object buffer; | 4693 Lisp_Object buffer; |
4694 Bufpos start, end; | 4694 Charbpos start, end; |
4695 int afterp; | 4695 int afterp; |
4696 int speccount; | 4696 int speccount; |
4697 }; | 4697 }; |
4698 | 4698 |
4699 static Lisp_Object | 4699 static Lisp_Object |
4725 the current buffer, in case we change it. Do the recording only | 4725 the current buffer, in case we change it. Do the recording only |
4726 once. | 4726 once. |
4727 | 4727 |
4728 One confusing thing here is that our caller never actually calls | 4728 One confusing thing here is that our caller never actually calls |
4729 unbind_to (closure.speccount, Qnil). This is because | 4729 unbind_to (closure.speccount, Qnil). This is because |
4730 map_extents_bytind() unbinds before, and with a smaller | 4730 map_extents_bytebpos() unbinds before, and with a smaller |
4731 speccount. The additional unbind_to() in | 4731 speccount. The additional unbind_to() in |
4732 report_extent_modification() would cause XEmacs to abort. */ | 4732 report_extent_modification() would cause XEmacs to abort. */ |
4733 if (closure->speccount == -1) | 4733 if (closure->speccount == -1) |
4734 { | 4734 { |
4735 closure->speccount = specpdl_depth (); | 4735 closure->speccount = specpdl_depth (); |
4762 } | 4762 } |
4763 return 0; | 4763 return 0; |
4764 } | 4764 } |
4765 | 4765 |
4766 void | 4766 void |
4767 report_extent_modification (Lisp_Object buffer, Bufpos start, Bufpos end, | 4767 report_extent_modification (Lisp_Object buffer, Charbpos start, Charbpos end, |
4768 int afterp) | 4768 int afterp) |
4769 { | 4769 { |
4770 struct report_extent_modification_closure closure; | 4770 struct report_extent_modification_closure closure; |
4771 | 4771 |
4772 closure.buffer = buffer; | 4772 closure.buffer = buffer; |
5668 /************************************************************************/ | 5668 /************************************************************************/ |
5669 | 5669 |
5670 /* copy/paste hooks */ | 5670 /* copy/paste hooks */ |
5671 | 5671 |
5672 static int | 5672 static int |
5673 run_extent_copy_paste_internal (EXTENT e, Bufpos from, Bufpos to, | 5673 run_extent_copy_paste_internal (EXTENT e, Charbpos from, Charbpos to, |
5674 Lisp_Object object, | 5674 Lisp_Object object, |
5675 Lisp_Object prop) | 5675 Lisp_Object prop) |
5676 { | 5676 { |
5677 /* This function can GC */ | 5677 /* This function can GC */ |
5678 Lisp_Object extent; | 5678 Lisp_Object extent; |
5695 } | 5695 } |
5696 return 1; | 5696 return 1; |
5697 } | 5697 } |
5698 | 5698 |
5699 static int | 5699 static int |
5700 run_extent_copy_function (EXTENT e, Bytind from, Bytind to) | 5700 run_extent_copy_function (EXTENT e, Bytebpos from, Bytebpos to) |
5701 { | 5701 { |
5702 Lisp_Object object = extent_object (e); | 5702 Lisp_Object object = extent_object (e); |
5703 /* This function can GC */ | 5703 /* This function can GC */ |
5704 return run_extent_copy_paste_internal | 5704 return run_extent_copy_paste_internal |
5705 (e, buffer_or_string_bytind_to_bufpos (object, from), | 5705 (e, buffer_or_string_bytebpos_to_charbpos (object, from), |
5706 buffer_or_string_bytind_to_bufpos (object, to), object, | 5706 buffer_or_string_bytebpos_to_charbpos (object, to), object, |
5707 Qcopy_function); | 5707 Qcopy_function); |
5708 } | 5708 } |
5709 | 5709 |
5710 static int | 5710 static int |
5711 run_extent_paste_function (EXTENT e, Bytind from, Bytind to, | 5711 run_extent_paste_function (EXTENT e, Bytebpos from, Bytebpos to, |
5712 Lisp_Object object) | 5712 Lisp_Object object) |
5713 { | 5713 { |
5714 /* This function can GC */ | 5714 /* This function can GC */ |
5715 return run_extent_copy_paste_internal | 5715 return run_extent_copy_paste_internal |
5716 (e, buffer_or_string_bytind_to_bufpos (object, from), | 5716 (e, buffer_or_string_bytebpos_to_charbpos (object, from), |
5717 buffer_or_string_bytind_to_bufpos (object, to), object, | 5717 buffer_or_string_bytebpos_to_charbpos (object, to), object, |
5718 Qpaste_function); | 5718 Qpaste_function); |
5719 } | 5719 } |
5720 | 5720 |
5721 static void | 5721 static void |
5722 update_extent (EXTENT extent, Bytind from, Bytind to) | 5722 update_extent (EXTENT extent, Bytebpos from, Bytebpos to) |
5723 { | 5723 { |
5724 set_extent_endpoints (extent, from, to, Qnil); | 5724 set_extent_endpoints (extent, from, to, Qnil); |
5725 } | 5725 } |
5726 | 5726 |
5727 /* Insert an extent, usually from the dup_list of a string which | 5727 /* Insert an extent, usually from the dup_list of a string which |
5728 has just been inserted. | 5728 has just been inserted. |
5729 This code does not handle the case of undo. | 5729 This code does not handle the case of undo. |
5730 */ | 5730 */ |
5731 static Lisp_Object | 5731 static Lisp_Object |
5732 insert_extent (EXTENT extent, Bytind new_start, Bytind new_end, | 5732 insert_extent (EXTENT extent, Bytebpos new_start, Bytebpos new_end, |
5733 Lisp_Object object, int run_hooks) | 5733 Lisp_Object object, int run_hooks) |
5734 { | 5734 { |
5735 /* This function can GC */ | 5735 /* This function can GC */ |
5736 Lisp_Object tmp; | 5736 Lisp_Object tmp; |
5737 | 5737 |
5747 else | 5747 else |
5748 update_extent (extent, new_start, new_end); | 5748 update_extent (extent, new_start, new_end); |
5749 } | 5749 } |
5750 else | 5750 else |
5751 { | 5751 { |
5752 Bytind exstart = extent_endpoint_bytind (extent, 0); | 5752 Bytebpos exstart = extent_endpoint_bytebpos (extent, 0); |
5753 Bytind exend = extent_endpoint_bytind (extent, 1); | 5753 Bytebpos exend = extent_endpoint_bytebpos (extent, 1); |
5754 | 5754 |
5755 if (exend < new_start || exstart > new_end) | 5755 if (exend < new_start || exstart > new_end) |
5756 goto copy_it; | 5756 goto copy_it; |
5757 else | 5757 else |
5758 { | 5758 { |
5791 */ | 5791 */ |
5792 (extent, start, end, no_hooks, buffer_or_string)) | 5792 (extent, start, end, no_hooks, buffer_or_string)) |
5793 { | 5793 { |
5794 EXTENT ext = decode_extent (extent, 0); | 5794 EXTENT ext = decode_extent (extent, 0); |
5795 Lisp_Object copy; | 5795 Lisp_Object copy; |
5796 Bytind s, e; | 5796 Bytebpos s, e; |
5797 | 5797 |
5798 buffer_or_string = decode_buffer_or_string (buffer_or_string); | 5798 buffer_or_string = decode_buffer_or_string (buffer_or_string); |
5799 get_buffer_or_string_range_byte (buffer_or_string, start, end, &s, &e, | 5799 get_buffer_or_string_range_byte (buffer_or_string, start, end, &s, &e, |
5800 GB_ALLOW_PAST_ACCESSIBLE); | 5800 GB_ALLOW_PAST_ACCESSIBLE); |
5801 | 5801 |
5811 | 5811 |
5812 /* adding buffer extents to a string */ | 5812 /* adding buffer extents to a string */ |
5813 | 5813 |
5814 struct add_string_extents_arg | 5814 struct add_string_extents_arg |
5815 { | 5815 { |
5816 Bytind from; | 5816 Bytebpos from; |
5817 Bytecount length; | 5817 Bytecount length; |
5818 Lisp_Object string; | 5818 Lisp_Object string; |
5819 }; | 5819 }; |
5820 | 5820 |
5821 static int | 5821 static int |
5822 add_string_extents_mapper (EXTENT extent, void *arg) | 5822 add_string_extents_mapper (EXTENT extent, void *arg) |
5823 { | 5823 { |
5824 /* This function can GC */ | 5824 /* This function can GC */ |
5825 struct add_string_extents_arg *closure = | 5825 struct add_string_extents_arg *closure = |
5826 (struct add_string_extents_arg *) arg; | 5826 (struct add_string_extents_arg *) arg; |
5827 Bytecount start = extent_endpoint_bytind (extent, 0) - closure->from; | 5827 Bytecount start = extent_endpoint_bytebpos (extent, 0) - closure->from; |
5828 Bytecount end = extent_endpoint_bytind (extent, 1) - closure->from; | 5828 Bytecount end = extent_endpoint_bytebpos (extent, 1) - closure->from; |
5829 | 5829 |
5830 if (extent_duplicable_p (extent)) | 5830 if (extent_duplicable_p (extent)) |
5831 { | 5831 { |
5832 start = max (start, 0); | 5832 start = max (start, 0); |
5833 end = min (end, closure->length); | 5833 end = min (end, closure->length); |
5846 } | 5846 } |
5847 | 5847 |
5848 /* Add the extents in buffer BUF from OPOINT to OPOINT+LENGTH to | 5848 /* Add the extents in buffer BUF from OPOINT to OPOINT+LENGTH to |
5849 the string STRING. */ | 5849 the string STRING. */ |
5850 void | 5850 void |
5851 add_string_extents (Lisp_Object string, struct buffer *buf, Bytind opoint, | 5851 add_string_extents (Lisp_Object string, struct buffer *buf, Bytebpos opoint, |
5852 Bytecount length) | 5852 Bytecount length) |
5853 { | 5853 { |
5854 /* This function can GC */ | 5854 /* This function can GC */ |
5855 struct add_string_extents_arg closure; | 5855 struct add_string_extents_arg closure; |
5856 struct gcpro gcpro1, gcpro2; | 5856 struct gcpro gcpro1, gcpro2; |
5859 closure.from = opoint; | 5859 closure.from = opoint; |
5860 closure.length = length; | 5860 closure.length = length; |
5861 closure.string = string; | 5861 closure.string = string; |
5862 buffer = make_buffer (buf); | 5862 buffer = make_buffer (buf); |
5863 GCPRO2 (buffer, string); | 5863 GCPRO2 (buffer, string); |
5864 map_extents_bytind (opoint, opoint + length, add_string_extents_mapper, | 5864 map_extents_bytebpos (opoint, opoint + length, add_string_extents_mapper, |
5865 (void *) &closure, buffer, 0, | 5865 (void *) &closure, buffer, 0, |
5866 /* ignore extents that just abut the region */ | 5866 /* ignore extents that just abut the region */ |
5867 ME_END_CLOSED | ME_ALL_EXTENTS_OPEN | | 5867 ME_END_CLOSED | ME_ALL_EXTENTS_OPEN | |
5868 /* we are calling E-Lisp (the extent's copy function) | 5868 /* we are calling E-Lisp (the extent's copy function) |
5869 so anything might happen */ | 5869 so anything might happen */ |
5873 | 5873 |
5874 struct splice_in_string_extents_arg | 5874 struct splice_in_string_extents_arg |
5875 { | 5875 { |
5876 Bytecount pos; | 5876 Bytecount pos; |
5877 Bytecount length; | 5877 Bytecount length; |
5878 Bytind opoint; | 5878 Bytebpos opoint; |
5879 Lisp_Object buffer; | 5879 Lisp_Object buffer; |
5880 }; | 5880 }; |
5881 | 5881 |
5882 static int | 5882 static int |
5883 splice_in_string_extents_mapper (EXTENT extent, void *arg) | 5883 splice_in_string_extents_mapper (EXTENT extent, void *arg) |
5888 /* BASE_START and BASE_END are the limits in the buffer of the string | 5888 /* BASE_START and BASE_END are the limits in the buffer of the string |
5889 that was just inserted. | 5889 that was just inserted. |
5890 | 5890 |
5891 NEW_START and NEW_END are the prospective buffer positions of the | 5891 NEW_START and NEW_END are the prospective buffer positions of the |
5892 extent that is going into the buffer. */ | 5892 extent that is going into the buffer. */ |
5893 Bytind base_start = closure->opoint; | 5893 Bytebpos base_start = closure->opoint; |
5894 Bytind base_end = base_start + closure->length; | 5894 Bytebpos base_end = base_start + closure->length; |
5895 Bytind new_start = (base_start + extent_endpoint_bytind (extent, 0) - | 5895 Bytebpos new_start = (base_start + extent_endpoint_bytebpos (extent, 0) - |
5896 closure->pos); | 5896 closure->pos); |
5897 Bytind new_end = (base_start + extent_endpoint_bytind (extent, 1) - | 5897 Bytebpos new_end = (base_start + extent_endpoint_bytebpos (extent, 1) - |
5898 closure->pos); | 5898 closure->pos); |
5899 | 5899 |
5900 if (new_start < base_start) | 5900 if (new_start < base_start) |
5901 new_start = base_start; | 5901 new_start = base_start; |
5902 if (new_end > base_end) | 5902 if (new_end > base_end) |
5920 length LENGTH) into buffer BUF at OPOINT. Do whatever is necessary | 5920 length LENGTH) into buffer BUF at OPOINT. Do whatever is necessary |
5921 to get the string's extents into the buffer. */ | 5921 to get the string's extents into the buffer. */ |
5922 | 5922 |
5923 void | 5923 void |
5924 splice_in_string_extents (Lisp_Object string, struct buffer *buf, | 5924 splice_in_string_extents (Lisp_Object string, struct buffer *buf, |
5925 Bytind opoint, Bytecount length, Bytecount pos) | 5925 Bytebpos opoint, Bytecount length, Bytecount pos) |
5926 { | 5926 { |
5927 struct splice_in_string_extents_arg closure; | 5927 struct splice_in_string_extents_arg closure; |
5928 struct gcpro gcpro1, gcpro2; | 5928 struct gcpro gcpro1, gcpro2; |
5929 Lisp_Object buffer; | 5929 Lisp_Object buffer; |
5930 | 5930 |
5932 closure.opoint = opoint; | 5932 closure.opoint = opoint; |
5933 closure.pos = pos; | 5933 closure.pos = pos; |
5934 closure.length = length; | 5934 closure.length = length; |
5935 closure.buffer = buffer; | 5935 closure.buffer = buffer; |
5936 GCPRO2 (buffer, string); | 5936 GCPRO2 (buffer, string); |
5937 map_extents_bytind (pos, pos + length, | 5937 map_extents_bytebpos (pos, pos + length, |
5938 splice_in_string_extents_mapper, | 5938 splice_in_string_extents_mapper, |
5939 (void *) &closure, string, 0, | 5939 (void *) &closure, string, 0, |
5940 /* ignore extents that just abut the region */ | 5940 /* ignore extents that just abut the region */ |
5941 ME_END_CLOSED | ME_ALL_EXTENTS_OPEN | | 5941 ME_END_CLOSED | ME_ALL_EXTENTS_OPEN | |
5942 /* we are calling E-Lisp (the extent's copy function) | 5942 /* we are calling E-Lisp (the extent's copy function) |
5964 { | 5964 { |
5965 struct copy_string_extents_arg *closure = | 5965 struct copy_string_extents_arg *closure = |
5966 (struct copy_string_extents_arg *) arg; | 5966 (struct copy_string_extents_arg *) arg; |
5967 Bytecount old_start, old_end, new_start, new_end; | 5967 Bytecount old_start, old_end, new_start, new_end; |
5968 | 5968 |
5969 old_start = extent_endpoint_bytind (extent, 0); | 5969 old_start = extent_endpoint_bytebpos (extent, 0); |
5970 old_end = extent_endpoint_bytind (extent, 1); | 5970 old_end = extent_endpoint_bytebpos (extent, 1); |
5971 | 5971 |
5972 old_start = max (closure->old_pos, old_start); | 5972 old_start = max (closure->old_pos, old_start); |
5973 old_end = min (closure->old_pos + closure->length, old_end); | 5973 old_end = min (closure->old_pos + closure->length, old_end); |
5974 | 5974 |
5975 if (old_start >= old_end) | 5975 if (old_start >= old_end) |
5998 closure.new_pos = new_pos; | 5998 closure.new_pos = new_pos; |
5999 closure.old_pos = old_pos; | 5999 closure.old_pos = old_pos; |
6000 closure.new_string = new_string; | 6000 closure.new_string = new_string; |
6001 closure.length = length; | 6001 closure.length = length; |
6002 GCPRO2 (new_string, old_string); | 6002 GCPRO2 (new_string, old_string); |
6003 map_extents_bytind (old_pos, old_pos + length, | 6003 map_extents_bytebpos (old_pos, old_pos + length, |
6004 copy_string_extents_mapper, | 6004 copy_string_extents_mapper, |
6005 (void *) &closure, old_string, 0, | 6005 (void *) &closure, old_string, 0, |
6006 /* ignore extents that just abut the region */ | 6006 /* ignore extents that just abut the region */ |
6007 ME_END_CLOSED | ME_ALL_EXTENTS_OPEN | | 6007 ME_END_CLOSED | ME_ALL_EXTENTS_OPEN | |
6008 /* we are calling E-Lisp (the extent's copy function) | 6008 /* we are calling E-Lisp (the extent's copy function) |
6028 | 6028 |
6029 Lisp_Object Qtext_prop; | 6029 Lisp_Object Qtext_prop; |
6030 Lisp_Object Qtext_prop_extent_paste_function; | 6030 Lisp_Object Qtext_prop_extent_paste_function; |
6031 | 6031 |
6032 static Lisp_Object | 6032 static Lisp_Object |
6033 get_text_property_bytind (Bytind position, Lisp_Object prop, | 6033 get_text_property_bytebpos (Bytebpos position, Lisp_Object prop, |
6034 Lisp_Object object, enum extent_at_flag fl, | 6034 Lisp_Object object, enum extent_at_flag fl, |
6035 int text_props_only) | 6035 int text_props_only) |
6036 { | 6036 { |
6037 Lisp_Object extent; | 6037 Lisp_Object extent; |
6038 | 6038 |
6039 /* text_props_only specifies whether we only consider text-property | 6039 /* text_props_only specifies whether we only consider text-property |
6040 extents (those with the 'text-prop property set) or all extents. */ | 6040 extents (those with the 'text-prop property set) or all extents. */ |
6041 if (!text_props_only) | 6041 if (!text_props_only) |
6042 extent = extent_at_bytind (position, object, prop, 0, fl, 0); | 6042 extent = extent_at_bytebpos (position, object, prop, 0, fl, 0); |
6043 else | 6043 else |
6044 { | 6044 { |
6045 EXTENT prior = 0; | 6045 EXTENT prior = 0; |
6046 while (1) | 6046 while (1) |
6047 { | 6047 { |
6048 extent = extent_at_bytind (position, object, Qtext_prop, prior, | 6048 extent = extent_at_bytebpos (position, object, Qtext_prop, prior, |
6049 fl, 0); | 6049 fl, 0); |
6050 if (NILP (extent)) | 6050 if (NILP (extent)) |
6051 return Qnil; | 6051 return Qnil; |
6052 if (EQ (prop, Fextent_property (extent, Qtext_prop, Qnil))) | 6052 if (EQ (prop, Fextent_property (extent, Qtext_prop, Qnil))) |
6053 break; | 6053 break; |
6064 | 6064 |
6065 static Lisp_Object | 6065 static Lisp_Object |
6066 get_text_property_1 (Lisp_Object pos, Lisp_Object prop, Lisp_Object object, | 6066 get_text_property_1 (Lisp_Object pos, Lisp_Object prop, Lisp_Object object, |
6067 Lisp_Object at_flag, int text_props_only) | 6067 Lisp_Object at_flag, int text_props_only) |
6068 { | 6068 { |
6069 Bytind position; | 6069 Bytebpos position; |
6070 int invert = 0; | 6070 int invert = 0; |
6071 | 6071 |
6072 object = decode_buffer_or_string (object); | 6072 object = decode_buffer_or_string (object); |
6073 position = get_buffer_or_string_pos_byte (object, pos, GB_NO_ERROR_IF_BAD); | 6073 position = get_buffer_or_string_pos_byte (object, pos, GB_NO_ERROR_IF_BAD); |
6074 | 6074 |
6088 invert = 1; | 6088 invert = 1; |
6089 } | 6089 } |
6090 | 6090 |
6091 { | 6091 { |
6092 Lisp_Object val = | 6092 Lisp_Object val = |
6093 get_text_property_bytind (position, prop, object, | 6093 get_text_property_bytebpos (position, prop, object, |
6094 decode_extent_at_flag (at_flag), | 6094 decode_extent_at_flag (at_flag), |
6095 text_props_only); | 6095 text_props_only); |
6096 if (invert) | 6096 if (invert) |
6097 val = NILP (val) ? Qt : Qnil; | 6097 val = NILP (val) ? Qt : Qnil; |
6098 return val; | 6098 return val; |
6154 */ | 6154 */ |
6155 | 6155 |
6156 struct put_text_prop_arg | 6156 struct put_text_prop_arg |
6157 { | 6157 { |
6158 Lisp_Object prop, value; /* The property and value we are storing */ | 6158 Lisp_Object prop, value; /* The property and value we are storing */ |
6159 Bytind start, end; /* The region into which we are storing it */ | 6159 Bytebpos start, end; /* The region into which we are storing it */ |
6160 Lisp_Object object; | 6160 Lisp_Object object; |
6161 Lisp_Object the_extent; /* Our chosen extent; this is used for | 6161 Lisp_Object the_extent; /* Our chosen extent; this is used for |
6162 communication between subsequent passes. */ | 6162 communication between subsequent passes. */ |
6163 int changed_p; /* Output: whether we have modified anything */ | 6163 int changed_p; /* Output: whether we have modified anything */ |
6164 }; | 6164 }; |
6168 { | 6168 { |
6169 struct put_text_prop_arg *closure = (struct put_text_prop_arg *) arg; | 6169 struct put_text_prop_arg *closure = (struct put_text_prop_arg *) arg; |
6170 | 6170 |
6171 Lisp_Object object = closure->object; | 6171 Lisp_Object object = closure->object; |
6172 Lisp_Object value = closure->value; | 6172 Lisp_Object value = closure->value; |
6173 Bytind e_start, e_end; | 6173 Bytebpos e_start, e_end; |
6174 Bytind start = closure->start; | 6174 Bytebpos start = closure->start; |
6175 Bytind end = closure->end; | 6175 Bytebpos end = closure->end; |
6176 Lisp_Object extent, e_val; | 6176 Lisp_Object extent, e_val; |
6177 int is_eq; | 6177 int is_eq; |
6178 | 6178 |
6179 XSETEXTENT (extent, e); | 6179 XSETEXTENT (extent, e); |
6180 | 6180 |
6184 openness later on in put_text_prop_openness_mapper(). */ | 6184 openness later on in put_text_prop_openness_mapper(). */ |
6185 if (!EQ (Fextent_property (extent, Qtext_prop, Qnil), closure->prop)) | 6185 if (!EQ (Fextent_property (extent, Qtext_prop, Qnil), closure->prop)) |
6186 /* It's not for this property; do nothing. */ | 6186 /* It's not for this property; do nothing. */ |
6187 return 0; | 6187 return 0; |
6188 | 6188 |
6189 e_start = extent_endpoint_bytind (e, 0); | 6189 e_start = extent_endpoint_bytebpos (e, 0); |
6190 e_end = extent_endpoint_bytind (e, 1); | 6190 e_end = extent_endpoint_bytebpos (e, 1); |
6191 e_val = Fextent_property (extent, closure->prop, Qnil); | 6191 e_val = Fextent_property (extent, closure->prop, Qnil); |
6192 is_eq = EQ (value, e_val); | 6192 is_eq = EQ (value, e_val); |
6193 | 6193 |
6194 if (!NILP (value) && NILP (closure->the_extent) && is_eq) | 6194 if (!NILP (value) && NILP (closure->the_extent) && is_eq) |
6195 { | 6195 { |
6199 side-effecting the kill ring (that is, we never change the property | 6199 side-effecting the kill ring (that is, we never change the property |
6200 on an extent after it has been created.) | 6200 on an extent after it has been created.) |
6201 */ | 6201 */ |
6202 if (e_start != start || e_end != end) | 6202 if (e_start != start || e_end != end) |
6203 { | 6203 { |
6204 Bytind new_start = min (e_start, start); | 6204 Bytebpos new_start = min (e_start, start); |
6205 Bytind new_end = max (e_end, end); | 6205 Bytebpos new_end = max (e_end, end); |
6206 set_extent_endpoints (e, new_start, new_end, Qnil); | 6206 set_extent_endpoints (e, new_start, new_end, Qnil); |
6207 /* If we changed the endpoint, then we need to set its | 6207 /* If we changed the endpoint, then we need to set its |
6208 openness. */ | 6208 openness. */ |
6209 set_extent_openness (e, new_start != e_start | 6209 set_extent_openness (e, new_start != e_start |
6210 ? !NILP (get_text_property_bytind | 6210 ? !NILP (get_text_property_bytebpos |
6211 (start, Qstart_open, object, | 6211 (start, Qstart_open, object, |
6212 EXTENT_AT_AFTER, 1)) : -1, | 6212 EXTENT_AT_AFTER, 1)) : -1, |
6213 new_end != e_end | 6213 new_end != e_end |
6214 ? NILP (get_text_property_bytind | 6214 ? NILP (get_text_property_bytebpos |
6215 (end - 1, Qend_closed, object, | 6215 (end - 1, Qend_closed, object, |
6216 EXTENT_AT_AFTER, 1)) | 6216 EXTENT_AT_AFTER, 1)) |
6217 : -1); | 6217 : -1); |
6218 closure->changed_p = 1; | 6218 closure->changed_p = 1; |
6219 } | 6219 } |
6251 decided to reuse, so we can remove this existing extent as well (the | 6251 decided to reuse, so we can remove this existing extent as well (the |
6252 whole thing, even the part outside of the region) and extend | 6252 whole thing, even the part outside of the region) and extend |
6253 the-extent to cover it, resulting in the minimum number of extents in | 6253 the-extent to cover it, resulting in the minimum number of extents in |
6254 the buffer. | 6254 the buffer. |
6255 */ | 6255 */ |
6256 Bytind the_start = extent_endpoint_bytind (te, 0); | 6256 Bytebpos the_start = extent_endpoint_bytebpos (te, 0); |
6257 Bytind the_end = extent_endpoint_bytind (te, 1); | 6257 Bytebpos the_end = extent_endpoint_bytebpos (te, 1); |
6258 if (e_start != the_start && /* note AND not OR -- hmm, why is this | 6258 if (e_start != the_start && /* note AND not OR -- hmm, why is this |
6259 the case? I think it's because the | 6259 the case? I think it's because the |
6260 assumption that the text-property | 6260 assumption that the text-property |
6261 extents don't overlap makes it | 6261 extents don't overlap makes it |
6262 OK; changing it to an OR would | 6262 OK; changing it to an OR would |
6263 result in changed_p sometimes getting | 6263 result in changed_p sometimes getting |
6264 falsely marked. Is this bad? */ | 6264 falsely marked. Is this bad? */ |
6265 e_end != the_end) | 6265 e_end != the_end) |
6266 { | 6266 { |
6267 Bytind new_start = min (e_start, the_start); | 6267 Bytebpos new_start = min (e_start, the_start); |
6268 Bytind new_end = max (e_end, the_end); | 6268 Bytebpos new_end = max (e_end, the_end); |
6269 set_extent_endpoints (te, new_start, new_end, Qnil); | 6269 set_extent_endpoints (te, new_start, new_end, Qnil); |
6270 /* If we changed the endpoint, then we need to set its | 6270 /* If we changed the endpoint, then we need to set its |
6271 openness. We are setting the endpoint to be the same as | 6271 openness. We are setting the endpoint to be the same as |
6272 that of the extent we're about to remove, and we assume | 6272 that of the extent we're about to remove, and we assume |
6273 (the invariant mentioned above) that extent has the | 6273 (the invariant mentioned above) that extent has the |
6286 decrease its end position. | 6286 decrease its end position. |
6287 */ | 6287 */ |
6288 if (e_end != start) | 6288 if (e_end != start) |
6289 { | 6289 { |
6290 set_extent_endpoints (e, e_start, start, Qnil); | 6290 set_extent_endpoints (e, e_start, start, Qnil); |
6291 set_extent_openness (e, -1, NILP (get_text_property_bytind | 6291 set_extent_openness (e, -1, NILP (get_text_property_bytebpos |
6292 (start - 1, Qend_closed, object, | 6292 (start - 1, Qend_closed, object, |
6293 EXTENT_AT_AFTER, 1))); | 6293 EXTENT_AT_AFTER, 1))); |
6294 closure->changed_p = 1; | 6294 closure->changed_p = 1; |
6295 } | 6295 } |
6296 } | 6296 } |
6300 increase its start position. | 6300 increase its start position. |
6301 */ | 6301 */ |
6302 if (e_start != end) | 6302 if (e_start != end) |
6303 { | 6303 { |
6304 set_extent_endpoints (e, end, e_end, Qnil); | 6304 set_extent_endpoints (e, end, e_end, Qnil); |
6305 set_extent_openness (e, !NILP (get_text_property_bytind | 6305 set_extent_openness (e, !NILP (get_text_property_bytebpos |
6306 (end, Qstart_open, object, | 6306 (end, Qstart_open, object, |
6307 EXTENT_AT_AFTER, 1)), -1); | 6307 EXTENT_AT_AFTER, 1)), -1); |
6308 closure->changed_p = 1; | 6308 closure->changed_p = 1; |
6309 } | 6309 } |
6310 } | 6310 } |
6311 else | 6311 else |
6312 { | 6312 { |
6313 /* Otherwise, `extent' straddles the region. We need to split it. | 6313 /* Otherwise, `extent' straddles the region. We need to split it. |
6314 */ | 6314 */ |
6315 set_extent_endpoints (e, e_start, start, Qnil); | 6315 set_extent_endpoints (e, e_start, start, Qnil); |
6316 set_extent_openness (e, -1, NILP (get_text_property_bytind | 6316 set_extent_openness (e, -1, NILP (get_text_property_bytebpos |
6317 (start - 1, Qend_closed, object, | 6317 (start - 1, Qend_closed, object, |
6318 EXTENT_AT_AFTER, 1))); | 6318 EXTENT_AT_AFTER, 1))); |
6319 set_extent_openness (copy_extent (e, end, e_end, extent_object (e)), | 6319 set_extent_openness (copy_extent (e, end, e_end, extent_object (e)), |
6320 !NILP (get_text_property_bytind | 6320 !NILP (get_text_property_bytebpos |
6321 (end, Qstart_open, object, | 6321 (end, Qstart_open, object, |
6322 EXTENT_AT_AFTER, 1)), -1); | 6322 EXTENT_AT_AFTER, 1)), -1); |
6323 closure->changed_p = 1; | 6323 closure->changed_p = 1; |
6324 } | 6324 } |
6325 | 6325 |
6328 | 6328 |
6329 static int | 6329 static int |
6330 put_text_prop_openness_mapper (EXTENT e, void *arg) | 6330 put_text_prop_openness_mapper (EXTENT e, void *arg) |
6331 { | 6331 { |
6332 struct put_text_prop_arg *closure = (struct put_text_prop_arg *) arg; | 6332 struct put_text_prop_arg *closure = (struct put_text_prop_arg *) arg; |
6333 Bytind e_start, e_end; | 6333 Bytebpos e_start, e_end; |
6334 Bytind start = closure->start; | 6334 Bytebpos start = closure->start; |
6335 Bytind end = closure->end; | 6335 Bytebpos end = closure->end; |
6336 Lisp_Object extent; | 6336 Lisp_Object extent; |
6337 XSETEXTENT (extent, e); | 6337 XSETEXTENT (extent, e); |
6338 e_start = extent_endpoint_bytind (e, 0); | 6338 e_start = extent_endpoint_bytebpos (e, 0); |
6339 e_end = extent_endpoint_bytind (e, 1); | 6339 e_end = extent_endpoint_bytebpos (e, 1); |
6340 | 6340 |
6341 if (NILP (Fextent_property (extent, Qtext_prop, Qnil))) | 6341 if (NILP (Fextent_property (extent, Qtext_prop, Qnil))) |
6342 { | 6342 { |
6343 /* It's not a text-property extent; do nothing. */ | 6343 /* It's not a text-property extent; do nothing. */ |
6344 ; | 6344 ; |
6353 | 6353 |
6354 return 0; /* to continue mapping. */ | 6354 return 0; /* to continue mapping. */ |
6355 } | 6355 } |
6356 | 6356 |
6357 static int | 6357 static int |
6358 put_text_prop (Bytind start, Bytind end, Lisp_Object object, | 6358 put_text_prop (Bytebpos start, Bytebpos end, Lisp_Object object, |
6359 Lisp_Object prop, Lisp_Object value, | 6359 Lisp_Object prop, Lisp_Object value, |
6360 int duplicable_p) | 6360 int duplicable_p) |
6361 { | 6361 { |
6362 /* This function can GC */ | 6362 /* This function can GC */ |
6363 struct put_text_prop_arg closure; | 6363 struct put_text_prop_arg closure; |
6386 closure.end = end; | 6386 closure.end = end; |
6387 closure.object = object; | 6387 closure.object = object; |
6388 closure.changed_p = 0; | 6388 closure.changed_p = 0; |
6389 closure.the_extent = Qnil; | 6389 closure.the_extent = Qnil; |
6390 | 6390 |
6391 map_extents_bytind (start, end, | 6391 map_extents_bytebpos (start, end, |
6392 put_text_prop_mapper, | 6392 put_text_prop_mapper, |
6393 (void *) &closure, object, 0, | 6393 (void *) &closure, object, 0, |
6394 /* get all extents that abut the region */ | 6394 /* get all extents that abut the region */ |
6395 ME_ALL_EXTENTS_CLOSED | ME_END_CLOSED | | 6395 ME_ALL_EXTENTS_CLOSED | ME_END_CLOSED | |
6396 /* it might QUIT or error if the user has | 6396 /* it might QUIT or error if the user has |
6397 fucked with the extent plist. */ | 6397 fucked with the extent plist. */ |
6398 /* #### dmoore - I think this should include | 6398 /* #### dmoore - I think this should include |
6399 ME_MIGHT_MOVE_SOE, since the callback function | 6399 ME_MIGHT_MOVE_SOE, since the callback function |
6400 might recurse back into map_extents_bytind. */ | 6400 might recurse back into map_extents_bytebpos. */ |
6401 ME_MIGHT_THROW | | 6401 ME_MIGHT_THROW | |
6402 ME_MIGHT_MODIFY_EXTENTS); | 6402 ME_MIGHT_MODIFY_EXTENTS); |
6403 | 6403 |
6404 /* If we made it through the loop without reusing an extent | 6404 /* If we made it through the loop without reusing an extent |
6405 (and we want there to be one) make it now. | 6405 (and we want there to be one) make it now. |
6417 extent_duplicable_p (XEXTENT (extent)) = 1; | 6417 extent_duplicable_p (XEXTENT (extent)) = 1; |
6418 Fset_extent_property (extent, Qpaste_function, | 6418 Fset_extent_property (extent, Qpaste_function, |
6419 Qtext_prop_extent_paste_function); | 6419 Qtext_prop_extent_paste_function); |
6420 } | 6420 } |
6421 set_extent_openness (XEXTENT (extent), | 6421 set_extent_openness (XEXTENT (extent), |
6422 !NILP (get_text_property_bytind | 6422 !NILP (get_text_property_bytebpos |
6423 (start, Qstart_open, object, | 6423 (start, Qstart_open, object, |
6424 EXTENT_AT_AFTER, 1)), | 6424 EXTENT_AT_AFTER, 1)), |
6425 NILP (get_text_property_bytind | 6425 NILP (get_text_property_bytebpos |
6426 (end - 1, Qend_closed, object, | 6426 (end - 1, Qend_closed, object, |
6427 EXTENT_AT_AFTER, 1))); | 6427 EXTENT_AT_AFTER, 1))); |
6428 } | 6428 } |
6429 | 6429 |
6430 if (EQ (prop, Qstart_open) || EQ (prop, Qend_closed)) | 6430 if (EQ (prop, Qstart_open) || EQ (prop, Qend_closed)) |
6431 { | 6431 { |
6432 map_extents_bytind (start, end, | 6432 map_extents_bytebpos (start, end, |
6433 put_text_prop_openness_mapper, | 6433 put_text_prop_openness_mapper, |
6434 (void *) &closure, object, 0, | 6434 (void *) &closure, object, 0, |
6435 /* get all extents that abut the region */ | 6435 /* get all extents that abut the region */ |
6436 ME_ALL_EXTENTS_CLOSED | ME_END_CLOSED | | 6436 ME_ALL_EXTENTS_CLOSED | ME_END_CLOSED | |
6437 ME_MIGHT_MODIFY_EXTENTS); | 6437 ME_MIGHT_MODIFY_EXTENTS); |
6448 defaults to the current buffer. | 6448 defaults to the current buffer. |
6449 */ | 6449 */ |
6450 (start, end, prop, value, object)) | 6450 (start, end, prop, value, object)) |
6451 { | 6451 { |
6452 /* This function can GC */ | 6452 /* This function can GC */ |
6453 Bytind s, e; | 6453 Bytebpos s, e; |
6454 | 6454 |
6455 object = decode_buffer_or_string (object); | 6455 object = decode_buffer_or_string (object); |
6456 get_buffer_or_string_range_byte (object, start, end, &s, &e, 0); | 6456 get_buffer_or_string_range_byte (object, start, end, &s, &e, 0); |
6457 put_text_prop (s, e, object, prop, value, 1); | 6457 put_text_prop (s, e, object, prop, value, 1); |
6458 return prop; | 6458 return prop; |
6468 defaults to the current buffer. | 6468 defaults to the current buffer. |
6469 */ | 6469 */ |
6470 (start, end, prop, value, object)) | 6470 (start, end, prop, value, object)) |
6471 { | 6471 { |
6472 /* This function can GC */ | 6472 /* This function can GC */ |
6473 Bytind s, e; | 6473 Bytebpos s, e; |
6474 | 6474 |
6475 object = decode_buffer_or_string (object); | 6475 object = decode_buffer_or_string (object); |
6476 get_buffer_or_string_range_byte (object, start, end, &s, &e, 0); | 6476 get_buffer_or_string_range_byte (object, start, end, &s, &e, 0); |
6477 put_text_prop (s, e, object, prop, value, 0); | 6477 put_text_prop (s, e, object, prop, value, 0); |
6478 return prop; | 6478 return prop; |
6487 */ | 6487 */ |
6488 (start, end, props, object)) | 6488 (start, end, props, object)) |
6489 { | 6489 { |
6490 /* This function can GC */ | 6490 /* This function can GC */ |
6491 int changed = 0; | 6491 int changed = 0; |
6492 Bytind s, e; | 6492 Bytebpos s, e; |
6493 | 6493 |
6494 object = decode_buffer_or_string (object); | 6494 object = decode_buffer_or_string (object); |
6495 get_buffer_or_string_range_byte (object, start, end, &s, &e, 0); | 6495 get_buffer_or_string_range_byte (object, start, end, &s, &e, 0); |
6496 CHECK_LIST (props); | 6496 CHECK_LIST (props); |
6497 for (; !NILP (props); props = Fcdr (Fcdr (props))) | 6497 for (; !NILP (props); props = Fcdr (Fcdr (props))) |
6515 */ | 6515 */ |
6516 (start, end, props, object)) | 6516 (start, end, props, object)) |
6517 { | 6517 { |
6518 /* This function can GC */ | 6518 /* This function can GC */ |
6519 int changed = 0; | 6519 int changed = 0; |
6520 Bytind s, e; | 6520 Bytebpos s, e; |
6521 | 6521 |
6522 object = decode_buffer_or_string (object); | 6522 object = decode_buffer_or_string (object); |
6523 get_buffer_or_string_range_byte (object, start, end, &s, &e, 0); | 6523 get_buffer_or_string_range_byte (object, start, end, &s, &e, 0); |
6524 CHECK_LIST (props); | 6524 CHECK_LIST (props); |
6525 for (; !NILP (props); props = Fcdr (Fcdr (props))) | 6525 for (; !NILP (props); props = Fcdr (Fcdr (props))) |
6540 */ | 6540 */ |
6541 (start, end, props, object)) | 6541 (start, end, props, object)) |
6542 { | 6542 { |
6543 /* This function can GC */ | 6543 /* This function can GC */ |
6544 int changed = 0; | 6544 int changed = 0; |
6545 Bytind s, e; | 6545 Bytebpos s, e; |
6546 | 6546 |
6547 object = decode_buffer_or_string (object); | 6547 object = decode_buffer_or_string (object); |
6548 get_buffer_or_string_range_byte (object, start, end, &s, &e, 0); | 6548 get_buffer_or_string_range_byte (object, start, end, &s, &e, 0); |
6549 CHECK_LIST (props); | 6549 CHECK_LIST (props); |
6550 for (; !NILP (props); props = Fcdr (Fcdr (props))) | 6550 for (; !NILP (props); props = Fcdr (Fcdr (props))) |
6617 the value of PROP. (Note that this situation will not happen if you always | 6617 the value of PROP. (Note that this situation will not happen if you always |
6618 use the text-property primitives.) | 6618 use the text-property primitives.) |
6619 */ | 6619 */ |
6620 (pos, prop, object, limit)) | 6620 (pos, prop, object, limit)) |
6621 { | 6621 { |
6622 Bufpos bpos; | 6622 Charbpos bpos; |
6623 Bufpos blim; | 6623 Charbpos blim; |
6624 Lisp_Object extent, value; | 6624 Lisp_Object extent, value; |
6625 int limit_was_nil; | 6625 int limit_was_nil; |
6626 | 6626 |
6627 object = decode_buffer_or_string (object); | 6627 object = decode_buffer_or_string (object); |
6628 bpos = get_buffer_or_string_pos_char (object, pos, 0); | 6628 bpos = get_buffer_or_string_pos_char (object, pos, 0); |
6684 the value of PROP. (Note that this situation will not happen if you always | 6684 the value of PROP. (Note that this situation will not happen if you always |
6685 use the text-property primitives.) | 6685 use the text-property primitives.) |
6686 */ | 6686 */ |
6687 (pos, prop, object, limit)) | 6687 (pos, prop, object, limit)) |
6688 { | 6688 { |
6689 Bufpos bpos; | 6689 Charbpos bpos; |
6690 Bufpos blim; | 6690 Charbpos blim; |
6691 Lisp_Object extent, value; | 6691 Lisp_Object extent, value; |
6692 int limit_was_nil; | 6692 int limit_was_nil; |
6693 | 6693 |
6694 object = decode_buffer_or_string (object); | 6694 object = decode_buffer_or_string (object); |
6695 bpos = get_buffer_or_string_pos_char (object, pos, 0); | 6695 bpos = get_buffer_or_string_pos_char (object, pos, 0); |