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);