diff options
| author | Dmitry Antipov | 2012-07-27 06:47:07 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2012-07-27 06:47:07 +0400 |
| commit | 6195f3845db9aa785e644f55c86270788b293740 (patch) | |
| tree | 7c3d2d715fdf0edb4789e736d42ad3b893c73ef9 /src | |
| parent | 562157c814037dcba58a20cd6908a95992c22283 (diff) | |
| download | emacs-6195f3845db9aa785e644f55c86270788b293740.tar.gz emacs-6195f3845db9aa785e644f55c86270788b293740.zip | |
Fast save_excursion_save and save_excursion_restore.
* lisp.h (struct Lisp_Excursion): New data type.
(PVEC_EXCURSION): New pseudovector type.
(XEXCURSION, XSETEXCURSION, EXCURSIONP): Convenient macros
to deal with it. Adjust comments.
(init_marker, attach_marker): New prototype.
(unchain_marker): Adjust prototype.
* marker.c (attach_marker): Change to global.
(init_marker): New function.
* alloc.c (Fmake_marker, build_marker): Use it.
(build_marker): More easserts.
(mark_object): Handle struct Lisp_Excursion.
* editfns.c (save_excursion_save, save_excursion_restore):
Reimplement to use struct Lisp_Excursion. Add comments.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 17 | ||||
| -rw-r--r-- | src/alloc.c | 53 | ||||
| -rw-r--r-- | src/editfns.c | 174 | ||||
| -rw-r--r-- | src/lisp.h | 47 | ||||
| -rw-r--r-- | src/marker.c | 21 |
5 files changed, 196 insertions, 116 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 7e91158ee36..e78a0365288 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,20 @@ | |||
| 1 | 2012-07-27 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 2 | |||
| 3 | Fast save_excursion_save and save_excursion_restore. | ||
| 4 | * lisp.h (struct Lisp_Excursion): New data type. | ||
| 5 | (PVEC_EXCURSION): New pseudovector type. | ||
| 6 | (XEXCURSION, XSETEXCURSION, EXCURSIONP): Convenient macros | ||
| 7 | to deal with it. Adjust comments. | ||
| 8 | (init_marker, attach_marker): New prototype. | ||
| 9 | (unchain_marker): Adjust prototype. | ||
| 10 | * marker.c (attach_marker): Change to global. | ||
| 11 | (init_marker): New function. | ||
| 12 | * alloc.c (Fmake_marker, build_marker): Use it. | ||
| 13 | (build_marker): More easserts. | ||
| 14 | (mark_object): Handle struct Lisp_Excursion. | ||
| 15 | * editfns.c (save_excursion_save, save_excursion_restore): | ||
| 16 | Reimplement to use struct Lisp_Excursion. Add comments. | ||
| 17 | |||
| 1 | 2012-07-26 Paul Eggert <eggert@cs.ucla.edu> | 18 | 2012-07-26 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 19 | ||
| 3 | Fix export of symbols to GDB (Bug#12036). | 20 | Fix export of symbols to GDB (Bug#12036). |
diff --git a/src/alloc.c b/src/alloc.c index ac6cb861c4d..5377b27e329 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -3653,17 +3653,10 @@ DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, | |||
| 3653 | doc: /* Return a newly allocated marker which does not point at any place. */) | 3653 | doc: /* Return a newly allocated marker which does not point at any place. */) |
| 3654 | (void) | 3654 | (void) |
| 3655 | { | 3655 | { |
| 3656 | register Lisp_Object val; | 3656 | register Lisp_Object marker = allocate_misc (Lisp_Misc_Marker); |
| 3657 | register struct Lisp_Marker *p; | ||
| 3658 | 3657 | ||
| 3659 | val = allocate_misc (Lisp_Misc_Marker); | 3658 | init_marker (XMARKER (marker), NULL, 0, 0, 0); |
| 3660 | p = XMARKER (val); | 3659 | return marker; |
| 3661 | p->buffer = 0; | ||
| 3662 | p->bytepos = 0; | ||
| 3663 | p->charpos = 0; | ||
| 3664 | p->next = NULL; | ||
| 3665 | p->insertion_type = 0; | ||
| 3666 | return val; | ||
| 3667 | } | 3660 | } |
| 3668 | 3661 | ||
| 3669 | /* Return a newly allocated marker which points into BUF | 3662 | /* Return a newly allocated marker which points into BUF |
| @@ -3672,24 +3665,23 @@ DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, | |||
| 3672 | Lisp_Object | 3665 | Lisp_Object |
| 3673 | build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) | 3666 | build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) |
| 3674 | { | 3667 | { |
| 3675 | Lisp_Object obj; | 3668 | register Lisp_Object marker = allocate_misc (Lisp_Misc_Marker); |
| 3676 | struct Lisp_Marker *m; | 3669 | |
| 3670 | /* Use Fmake_marker to create marker points to nowhere. */ | ||
| 3671 | eassert (buf != NULL); | ||
| 3677 | 3672 | ||
| 3678 | /* No dead buffers here. */ | 3673 | /* No dead buffers here. */ |
| 3679 | eassert (!NILP (BVAR (buf, name))); | 3674 | eassert (!NILP (BVAR (buf, name))); |
| 3680 | 3675 | ||
| 3681 | /* Every character is at least one byte. */ | 3676 | /* In a single-byte buffer, two positions must be equal. |
| 3682 | eassert (charpos <= bytepos); | 3677 | Otherwise, every character is at least one byte. */ |
| 3683 | 3678 | if (BUF_Z (buf) == BUF_Z_BYTE (buf)) | |
| 3684 | obj = allocate_misc (Lisp_Misc_Marker); | 3679 | eassert (charpos == bytepos); |
| 3685 | m = XMARKER (obj); | 3680 | else |
| 3686 | m->buffer = buf; | 3681 | eassert (charpos <= bytepos); |
| 3687 | m->charpos = charpos; | 3682 | |
| 3688 | m->bytepos = bytepos; | 3683 | init_marker (XMARKER (marker), buf, charpos, bytepos, 0); |
| 3689 | m->insertion_type = 0; | 3684 | return marker; |
| 3690 | m->next = BUF_MARKERS (buf); | ||
| 3691 | BUF_MARKERS (buf) = m; | ||
| 3692 | return obj; | ||
| 3693 | } | 3685 | } |
| 3694 | 3686 | ||
| 3695 | /* Put MARKER back on the free list after using it temporarily. */ | 3687 | /* Put MARKER back on the free list after using it temporarily. */ |
| @@ -6057,6 +6049,19 @@ mark_object (Lisp_Object arg) | |||
| 6057 | case PVEC_SUBR: | 6049 | case PVEC_SUBR: |
| 6058 | break; | 6050 | break; |
| 6059 | 6051 | ||
| 6052 | case PVEC_EXCURSION: | ||
| 6053 | { | ||
| 6054 | struct Lisp_Excursion *e = (struct Lisp_Excursion *) ptr; | ||
| 6055 | /* No Lisp_Objects but two special pointers to mark here. */ | ||
| 6056 | eassert (e->buffer != NULL); | ||
| 6057 | eassert (e->window != NULL); | ||
| 6058 | if (!VECTOR_MARKED_P (e->buffer)) | ||
| 6059 | mark_buffer (e->buffer); | ||
| 6060 | if (!VECTOR_MARKED_P (e->window)) | ||
| 6061 | mark_vectorlike ((struct Lisp_Vector *) e->window); | ||
| 6062 | } | ||
| 6063 | break; | ||
| 6064 | |||
| 6060 | case PVEC_FREE: | 6065 | case PVEC_FREE: |
| 6061 | abort (); | 6066 | abort (); |
| 6062 | 6067 | ||
diff --git a/src/editfns.c b/src/editfns.c index f174594dd97..8b6c29bc934 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -821,104 +821,104 @@ This function does not move point. */) | |||
| 821 | Qnil, Qt, Qnil); | 821 | Qnil, Qt, Qnil); |
| 822 | } | 822 | } |
| 823 | 823 | ||
| 824 | 824 | /* Record buffer state before entering Fsave_excursion. */ | |
| 825 | |||
| 825 | Lisp_Object | 826 | Lisp_Object |
| 826 | save_excursion_save (void) | 827 | save_excursion_save (void) |
| 827 | { | 828 | { |
| 828 | int visible = (XBUFFER (XWINDOW (selected_window)->buffer) | 829 | Lisp_Object excursion; |
| 829 | == current_buffer); | 830 | struct buffer *b = current_buffer; |
| 830 | 831 | struct window *w = XWINDOW (selected_window); | |
| 831 | return Fcons (Fpoint_marker (), | 832 | struct Lisp_Excursion *ex = xmalloc (sizeof *ex); |
| 832 | Fcons (Fcopy_marker (BVAR (current_buffer, mark), Qnil), | 833 | struct Lisp_Marker *m = XMARKER (BVAR (b, mark)); |
| 833 | Fcons (visible ? Qt : Qnil, | 834 | |
| 834 | Fcons (BVAR (current_buffer, mark_active), | 835 | ex->size = 0; |
| 835 | selected_window)))); | 836 | ex->buffer = b; |
| 837 | ex->window = w; | ||
| 838 | ex->visible = (XBUFFER (w->buffer) == b); | ||
| 839 | ex->active = !NILP (BVAR (b, mark_active)); | ||
| 840 | |||
| 841 | /* We do not initialize type and gcmarkbit since this marker | ||
| 842 | is never referenced via Lisp_Object and invisible for GC. */ | ||
| 843 | init_marker (&ex->point, b, PT, PT_BYTE, 0); | ||
| 844 | |||
| 845 | /* Likewise. Note that charpos and bytepos may be zero. */ | ||
| 846 | init_marker (&ex->mark, m->buffer, m->charpos, | ||
| 847 | m->bytepos, m->insertion_type); | ||
| 848 | |||
| 849 | /* Make it a pseudovector and return excursion object. */ | ||
| 850 | XSETTYPED_PVECTYPE (ex, size, PVEC_EXCURSION); | ||
| 851 | XSETEXCURSION (excursion, ex); | ||
| 852 | return excursion; | ||
| 836 | } | 853 | } |
| 837 | 854 | ||
| 855 | /* Restore buffer state before leaving Fsave_excursion. */ | ||
| 856 | |||
| 838 | Lisp_Object | 857 | Lisp_Object |
| 839 | save_excursion_restore (Lisp_Object info) | 858 | save_excursion_restore (Lisp_Object obj) |
| 840 | { | 859 | { |
| 841 | Lisp_Object tem, tem1, omark, nmark; | 860 | struct Lisp_Excursion *ex = XEXCURSION (obj); |
| 842 | struct gcpro gcpro1, gcpro2, gcpro3; | 861 | struct buffer *b = ex->buffer; |
| 843 | int visible_p; | ||
| 844 | |||
| 845 | tem = Fmarker_buffer (XCAR (info)); | ||
| 846 | /* If buffer being returned to is now deleted, avoid error */ | ||
| 847 | /* Otherwise could get error here while unwinding to top level | ||
| 848 | and crash */ | ||
| 849 | /* In that case, Fmarker_buffer returns nil now. */ | ||
| 850 | if (NILP (tem)) | ||
| 851 | return Qnil; | ||
| 852 | 862 | ||
| 853 | omark = nmark = Qnil; | 863 | eassert (b != NULL); |
| 854 | GCPRO3 (info, omark, nmark); | 864 | eassert (ex->window != NULL); |
| 855 | 865 | ||
| 856 | Fset_buffer (tem); | 866 | /* Restore buffer state only if the buffer is live. |
| 857 | 867 | Otherwise, just cancel an excursion state. */ | |
| 858 | /* Point marker. */ | 868 | |
| 859 | tem = XCAR (info); | 869 | if (!NILP (BVAR (b, name))) |
| 860 | Fgoto_char (tem); | ||
| 861 | unchain_marker (XMARKER (tem)); | ||
| 862 | |||
| 863 | /* Mark marker. */ | ||
| 864 | info = XCDR (info); | ||
| 865 | tem = XCAR (info); | ||
| 866 | omark = Fmarker_position (BVAR (current_buffer, mark)); | ||
| 867 | Fset_marker (BVAR (current_buffer, mark), tem, Fcurrent_buffer ()); | ||
| 868 | nmark = Fmarker_position (tem); | ||
| 869 | unchain_marker (XMARKER (tem)); | ||
| 870 | |||
| 871 | /* visible */ | ||
| 872 | info = XCDR (info); | ||
| 873 | visible_p = !NILP (XCAR (info)); | ||
| 874 | |||
| 875 | #if 0 /* We used to make the current buffer visible in the selected window | ||
| 876 | if that was true previously. That avoids some anomalies. | ||
| 877 | But it creates others, and it wasn't documented, and it is simpler | ||
| 878 | and cleaner never to alter the window/buffer connections. */ | ||
| 879 | tem1 = Fcar (tem); | ||
| 880 | if (!NILP (tem1) | ||
| 881 | && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer)) | ||
| 882 | Fswitch_to_buffer (Fcurrent_buffer (), Qnil); | ||
| 883 | #endif /* 0 */ | ||
| 884 | |||
| 885 | /* Mark active */ | ||
| 886 | info = XCDR (info); | ||
| 887 | tem = XCAR (info); | ||
| 888 | tem1 = BVAR (current_buffer, mark_active); | ||
| 889 | BVAR (current_buffer, mark_active) = tem; | ||
| 890 | |||
| 891 | /* If mark is active now, and either was not active | ||
| 892 | or was at a different place, run the activate hook. */ | ||
| 893 | if (! NILP (tem)) | ||
| 894 | { | ||
| 895 | if (! EQ (omark, nmark)) | ||
| 896 | { | ||
| 897 | tem = intern ("activate-mark-hook"); | ||
| 898 | Frun_hooks (1, &tem); | ||
| 899 | } | ||
| 900 | } | ||
| 901 | /* If mark has ceased to be active, run deactivate hook. */ | ||
| 902 | else if (! NILP (tem1)) | ||
| 903 | { | 870 | { |
| 904 | tem = intern ("deactivate-mark-hook"); | 871 | int active; |
| 905 | Frun_hooks (1, &tem); | 872 | struct Lisp_Marker *m; |
| 873 | ptrdiff_t oldpos, newpos; | ||
| 874 | |||
| 875 | /* Restore current buffer. */ | ||
| 876 | set_buffer_internal (b); | ||
| 877 | |||
| 878 | /* Restore buffer position. */ | ||
| 879 | SET_PT_BOTH (clip_to_bounds (BEGV, ex->point.charpos, ZV), | ||
| 880 | clip_to_bounds (BEGV_BYTE, ex->point.bytepos, ZV_BYTE)); | ||
| 881 | unchain_marker (&ex->point); | ||
| 882 | |||
| 883 | /* Restore mark if it was non-zero. */ | ||
| 884 | m = XMARKER (BVAR (b, mark)); | ||
| 885 | oldpos = m->charpos; | ||
| 886 | if (BEGV <= ex->mark.charpos) | ||
| 887 | attach_marker (m, b, ex->mark.charpos, ex->mark.bytepos); | ||
| 888 | newpos = ex->mark.charpos; | ||
| 889 | unchain_marker (&ex->mark); | ||
| 890 | |||
| 891 | /* If mark and region was active, restore them. */ | ||
| 892 | active = !NILP (BVAR (b, mark_active)); | ||
| 893 | BVAR (b, mark_active) = ex->active ? Qt : Qnil; | ||
| 894 | |||
| 895 | /* If mark is active now, and either was not active | ||
| 896 | or was at a different place, run the activate hook. */ | ||
| 897 | if (ex->active && oldpos != newpos) | ||
| 898 | { | ||
| 899 | obj = intern ("activate-mark-hook"); | ||
| 900 | Frun_hooks (1, &obj); | ||
| 901 | } | ||
| 902 | /* If mark has ceased to be active, run deactivate hook. */ | ||
| 903 | else if (active) | ||
| 904 | { | ||
| 905 | obj = intern ("deactivate-mark-hook"); | ||
| 906 | Frun_hooks (1, &obj); | ||
| 907 | } | ||
| 908 | |||
| 909 | /* If buffer was visible in a window, and a different window | ||
| 910 | was selected, and the old selected window is still showing | ||
| 911 | this buffer, restore point in that window. */ | ||
| 912 | if (ex->visible) | ||
| 913 | { | ||
| 914 | struct window *w = ex->window; | ||
| 915 | |||
| 916 | if (w != XWINDOW (selected_window) && XBUFFER (w->buffer) == b) | ||
| 917 | attach_marker (XMARKER (w->pointm), b, PT, PT_BYTE); | ||
| 918 | } | ||
| 906 | } | 919 | } |
| 907 | 920 | ||
| 908 | /* If buffer was visible in a window, and a different window was | 921 | xfree (ex); |
| 909 | selected, and the old selected window is still showing this | ||
| 910 | buffer, restore point in that window. */ | ||
| 911 | tem = XCDR (info); | ||
| 912 | if (visible_p | ||
| 913 | && !EQ (tem, selected_window) | ||
| 914 | && (tem1 = XWINDOW (tem)->buffer, | ||
| 915 | (/* Window is live... */ | ||
| 916 | BUFFERP (tem1) | ||
| 917 | /* ...and it shows the current buffer. */ | ||
| 918 | && XBUFFER (tem1) == current_buffer))) | ||
| 919 | Fset_window_point (tem, make_number (PT)); | ||
| 920 | |||
| 921 | UNGCPRO; | ||
| 922 | return Qnil; | 922 | return Qnil; |
| 923 | } | 923 | } |
| 924 | 924 | ||
diff --git a/src/lisp.h b/src/lisp.h index f845ea6bd12..55a4a297a39 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -379,6 +379,7 @@ enum pvec_type | |||
| 379 | PVEC_TERMINAL, | 379 | PVEC_TERMINAL, |
| 380 | PVEC_WINDOW_CONFIGURATION, | 380 | PVEC_WINDOW_CONFIGURATION, |
| 381 | PVEC_SUBR, | 381 | PVEC_SUBR, |
| 382 | PVEC_EXCURSION, | ||
| 382 | PVEC_OTHER, | 383 | PVEC_OTHER, |
| 383 | /* These last 4 are special because we OR them in fns.c:internal_equal, | 384 | /* These last 4 are special because we OR them in fns.c:internal_equal, |
| 384 | so they have to use a disjoint bit pattern: | 385 | so they have to use a disjoint bit pattern: |
| @@ -551,6 +552,8 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) | |||
| 551 | (struct terminal *) XUNTAG (a, Lisp_Vectorlike)) | 552 | (struct terminal *) XUNTAG (a, Lisp_Vectorlike)) |
| 552 | #define XSUBR(a) (eassert (SUBRP (a)), \ | 553 | #define XSUBR(a) (eassert (SUBRP (a)), \ |
| 553 | (struct Lisp_Subr *) XUNTAG (a, Lisp_Vectorlike)) | 554 | (struct Lisp_Subr *) XUNTAG (a, Lisp_Vectorlike)) |
| 555 | #define XEXCURSION(a) (eassert (EXCURSIONP (a)), \ | ||
| 556 | (struct Lisp_Excursion *) XUNTAG (a, Lisp_Vectorlike)) | ||
| 554 | #define XBUFFER(a) (eassert (BUFFERP (a)), \ | 557 | #define XBUFFER(a) (eassert (BUFFERP (a)), \ |
| 555 | (struct buffer *) XUNTAG (a, Lisp_Vectorlike)) | 558 | (struct buffer *) XUNTAG (a, Lisp_Vectorlike)) |
| 556 | #define XCHAR_TABLE(a) (eassert (CHAR_TABLE_P (a)), \ | 559 | #define XCHAR_TABLE(a) (eassert (CHAR_TABLE_P (a)), \ |
| @@ -603,9 +606,12 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) | |||
| 603 | #define XSETPROCESS(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)) | 606 | #define XSETPROCESS(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)) |
| 604 | #define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)) | 607 | #define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)) |
| 605 | #define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)) | 608 | #define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)) |
| 606 | /* XSETSUBR is special since Lisp_Subr lacks struct vectorlike_header. */ | 609 | /* These are special because both Lisp_Subr and Lisp_Excursion lacks |
| 610 | struct vectorlike_header. */ | ||
| 607 | #define XSETSUBR(a, b) \ | 611 | #define XSETSUBR(a, b) \ |
| 608 | XSETTYPED_PSEUDOVECTOR (a, b, XSUBR (a)->size, PVEC_SUBR) | 612 | XSETTYPED_PSEUDOVECTOR (a, b, XSUBR (a)->size, PVEC_SUBR) |
| 613 | #define XSETEXCURSION(a, b) \ | ||
| 614 | XSETTYPED_PSEUDOVECTOR (a, b, XEXCURSION (a)->size, PVEC_EXCURSION) | ||
| 609 | #define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED)) | 615 | #define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED)) |
| 610 | #define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)) | 616 | #define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)) |
| 611 | #define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)) | 617 | #define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)) |
| @@ -1522,6 +1528,33 @@ struct Lisp_Float | |||
| 1522 | #define XFLOAT_INIT(f,n) (XFLOAT (f)->u.data = (n)) | 1528 | #define XFLOAT_INIT(f,n) (XFLOAT (f)->u.data = (n)) |
| 1523 | #endif | 1529 | #endif |
| 1524 | 1530 | ||
| 1531 | /* This structure is used to record buffer state for Fsave_excursion. | ||
| 1532 | It's mostly treated as Lisp_Vector but allocated and freed explicitly | ||
| 1533 | with xmalloc and xfree, so there is no vectorlike_header here. */ | ||
| 1534 | |||
| 1535 | struct Lisp_Excursion | ||
| 1536 | { | ||
| 1537 | ptrdiff_t size; | ||
| 1538 | |||
| 1539 | /* Saved value of XWINDOW (selected_window). */ | ||
| 1540 | struct window *window; | ||
| 1541 | |||
| 1542 | /* Buffer where this excursion is in effect. */ | ||
| 1543 | struct buffer *buffer; | ||
| 1544 | |||
| 1545 | /* Non-zero if the window above has displayed the buffer. */ | ||
| 1546 | unsigned visible : 1; | ||
| 1547 | |||
| 1548 | /* Non-zero if this buffer has the mark active. */ | ||
| 1549 | unsigned active : 1; | ||
| 1550 | |||
| 1551 | /* Saved point. */ | ||
| 1552 | struct Lisp_Marker point; | ||
| 1553 | |||
| 1554 | /* Saved mark. May point to nowhere. */ | ||
| 1555 | struct Lisp_Marker mark; | ||
| 1556 | }; | ||
| 1557 | |||
| 1525 | /* A character, declared with the following typedef, is a member | 1558 | /* A character, declared with the following typedef, is a member |
| 1526 | of some character set associated with the current buffer. */ | 1559 | of some character set associated with the current buffer. */ |
| 1527 | #ifndef _UCHAR_T /* Protect against something in ctab.h on AIX. */ | 1560 | #ifndef _UCHAR_T /* Protect against something in ctab.h on AIX. */ |
| @@ -1704,8 +1737,10 @@ typedef struct { | |||
| 1704 | #define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS) | 1737 | #define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS) |
| 1705 | #define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW) | 1738 | #define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW) |
| 1706 | #define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL) | 1739 | #define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL) |
| 1707 | /* SUBRP is special since Lisp_Subr lacks struct vectorlike_header. */ | 1740 | /* These are special because both Lisp_Subr and Lisp_Excursion lacks |
| 1741 | struct vectorlike_header. */ | ||
| 1708 | #define SUBRP(x) TYPED_PSEUDOVECTORP (x, Lisp_Subr, PVEC_SUBR) | 1742 | #define SUBRP(x) TYPED_PSEUDOVECTORP (x, Lisp_Subr, PVEC_SUBR) |
| 1743 | #define EXCURSIONP(x) TYPED_PSEUDOVECTORP (x, Lisp_Excursion, PVEC_EXCURSION) | ||
| 1709 | #define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED) | 1744 | #define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED) |
| 1710 | #define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER) | 1745 | #define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER) |
| 1711 | #define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE) | 1746 | #define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE) |
| @@ -2919,11 +2954,15 @@ extern void clear_charpos_cache (struct buffer *); | |||
| 2919 | extern ptrdiff_t charpos_to_bytepos (ptrdiff_t); | 2954 | extern ptrdiff_t charpos_to_bytepos (ptrdiff_t); |
| 2920 | extern ptrdiff_t buf_charpos_to_bytepos (struct buffer *, ptrdiff_t); | 2955 | extern ptrdiff_t buf_charpos_to_bytepos (struct buffer *, ptrdiff_t); |
| 2921 | extern ptrdiff_t buf_bytepos_to_charpos (struct buffer *, ptrdiff_t); | 2956 | extern ptrdiff_t buf_bytepos_to_charpos (struct buffer *, ptrdiff_t); |
| 2922 | extern void unchain_marker (struct Lisp_Marker *marker); | 2957 | extern void unchain_marker (struct Lisp_Marker *); |
| 2923 | extern Lisp_Object set_marker_restricted (Lisp_Object, Lisp_Object, Lisp_Object); | 2958 | extern Lisp_Object set_marker_restricted (Lisp_Object, Lisp_Object, Lisp_Object); |
| 2924 | extern Lisp_Object set_marker_both (Lisp_Object, Lisp_Object, ptrdiff_t, ptrdiff_t); | 2959 | extern Lisp_Object set_marker_both (Lisp_Object, Lisp_Object, ptrdiff_t, ptrdiff_t); |
| 2925 | extern Lisp_Object set_marker_restricted_both (Lisp_Object, Lisp_Object, | 2960 | extern Lisp_Object set_marker_restricted_both (Lisp_Object, Lisp_Object, |
| 2926 | ptrdiff_t, ptrdiff_t); | 2961 | ptrdiff_t, ptrdiff_t); |
| 2962 | extern void init_marker (struct Lisp_Marker *, struct buffer *, | ||
| 2963 | ptrdiff_t, ptrdiff_t, int); | ||
| 2964 | extern void attach_marker (struct Lisp_Marker *, struct buffer *, | ||
| 2965 | ptrdiff_t, ptrdiff_t); | ||
| 2927 | extern Lisp_Object build_marker (struct buffer *, ptrdiff_t, ptrdiff_t); | 2966 | extern Lisp_Object build_marker (struct buffer *, ptrdiff_t, ptrdiff_t); |
| 2928 | extern void syms_of_marker (void); | 2967 | extern void syms_of_marker (void); |
| 2929 | 2968 | ||
diff --git a/src/marker.c b/src/marker.c index 0a93f4c180f..d63947d8c31 100644 --- a/src/marker.c +++ b/src/marker.c | |||
| @@ -425,9 +425,28 @@ Returns nil if MARKER points nowhere. */) | |||
| 425 | return Qnil; | 425 | return Qnil; |
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | /* Initialize just allocated Lisp_Marker. */ | ||
| 429 | |||
| 430 | void | ||
| 431 | init_marker (struct Lisp_Marker *m, struct buffer *b, | ||
| 432 | ptrdiff_t charpos, ptrdiff_t bytepos, int type) | ||
| 433 | { | ||
| 434 | m->buffer = b; | ||
| 435 | m->charpos = charpos; | ||
| 436 | m->bytepos = bytepos; | ||
| 437 | m->insertion_type = type; | ||
| 438 | if (b) | ||
| 439 | { | ||
| 440 | m->next = BUF_MARKERS (b); | ||
| 441 | BUF_MARKERS (b) = m; | ||
| 442 | } | ||
| 443 | else | ||
| 444 | m->next = NULL; | ||
| 445 | } | ||
| 446 | |||
| 428 | /* Change M so it points to B at CHARPOS and BYTEPOS. */ | 447 | /* Change M so it points to B at CHARPOS and BYTEPOS. */ |
| 429 | 448 | ||
| 430 | static inline void | 449 | void |
| 431 | attach_marker (struct Lisp_Marker *m, struct buffer *b, | 450 | attach_marker (struct Lisp_Marker *m, struct buffer *b, |
| 432 | ptrdiff_t charpos, ptrdiff_t bytepos) | 451 | ptrdiff_t charpos, ptrdiff_t bytepos) |
| 433 | { | 452 | { |