diff options
| author | Dmitry Antipov | 2012-07-27 11:51:52 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2012-07-27 11:51:52 +0400 |
| commit | eeaea515623db982d4e7d453711e6f0fad9c08d8 (patch) | |
| tree | 6c4f5398509d735e85151d480c8ba4756c1e5ec5 /src/editfns.c | |
| parent | 073c88c22c0064b60ec57b6dadef9d3a4736e6b5 (diff) | |
| download | emacs-eeaea515623db982d4e7d453711e6f0fad9c08d8.tar.gz emacs-eeaea515623db982d4e7d453711e6f0fad9c08d8.zip | |
Revert last save_excursion_save and save_excursion_restore changes.
* alloc.c, editfns.c, marker.c, lisp.h: Revert.
Lots of crashes reported by Chong Yidong <cyd@gnu.org>.
Diffstat (limited to 'src/editfns.c')
| -rw-r--r-- | src/editfns.c | 174 |
1 files changed, 87 insertions, 87 deletions
diff --git a/src/editfns.c b/src/editfns.c index 8b6c29bc934..f174594dd97 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 | /* Record buffer state before entering Fsave_excursion. */ | 824 | |
| 825 | |||
| 826 | Lisp_Object | 825 | Lisp_Object |
| 827 | save_excursion_save (void) | 826 | save_excursion_save (void) |
| 828 | { | 827 | { |
| 829 | Lisp_Object excursion; | 828 | int visible = (XBUFFER (XWINDOW (selected_window)->buffer) |
| 830 | struct buffer *b = current_buffer; | 829 | == current_buffer); |
| 831 | struct window *w = XWINDOW (selected_window); | 830 | |
| 832 | struct Lisp_Excursion *ex = xmalloc (sizeof *ex); | 831 | return Fcons (Fpoint_marker (), |
| 833 | struct Lisp_Marker *m = XMARKER (BVAR (b, mark)); | 832 | Fcons (Fcopy_marker (BVAR (current_buffer, mark), Qnil), |
| 834 | 833 | Fcons (visible ? Qt : Qnil, | |
| 835 | ex->size = 0; | 834 | Fcons (BVAR (current_buffer, mark_active), |
| 836 | ex->buffer = b; | 835 | selected_window)))); |
| 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; | ||
| 853 | } | 836 | } |
| 854 | 837 | ||
| 855 | /* Restore buffer state before leaving Fsave_excursion. */ | ||
| 856 | |||
| 857 | Lisp_Object | 838 | Lisp_Object |
| 858 | save_excursion_restore (Lisp_Object obj) | 839 | save_excursion_restore (Lisp_Object info) |
| 859 | { | 840 | { |
| 860 | struct Lisp_Excursion *ex = XEXCURSION (obj); | 841 | Lisp_Object tem, tem1, omark, nmark; |
| 861 | struct buffer *b = ex->buffer; | 842 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 862 | 843 | int visible_p; | |
| 863 | eassert (b != NULL); | 844 | |
| 864 | eassert (ex->window != NULL); | 845 | tem = Fmarker_buffer (XCAR (info)); |
| 865 | 846 | /* If buffer being returned to is now deleted, avoid error */ | |
| 866 | /* Restore buffer state only if the buffer is live. | 847 | /* Otherwise could get error here while unwinding to top level |
| 867 | Otherwise, just cancel an excursion state. */ | 848 | and crash */ |
| 849 | /* In that case, Fmarker_buffer returns nil now. */ | ||
| 850 | if (NILP (tem)) | ||
| 851 | return Qnil; | ||
| 868 | 852 | ||
| 869 | if (!NILP (BVAR (b, name))) | 853 | omark = nmark = Qnil; |
| 854 | GCPRO3 (info, omark, nmark); | ||
| 855 | |||
| 856 | Fset_buffer (tem); | ||
| 857 | |||
| 858 | /* Point marker. */ | ||
| 859 | tem = XCAR (info); | ||
| 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)) | ||
| 870 | { | 894 | { |
| 871 | int active; | 895 | if (! EQ (omark, nmark)) |
| 872 | struct Lisp_Marker *m; | 896 | { |
| 873 | ptrdiff_t oldpos, newpos; | 897 | tem = intern ("activate-mark-hook"); |
| 874 | 898 | Frun_hooks (1, &tem); | |
| 875 | /* Restore current buffer. */ | 899 | } |
| 876 | set_buffer_internal (b); | 900 | } |
| 877 | 901 | /* If mark has ceased to be active, run deactivate hook. */ | |
| 878 | /* Restore buffer position. */ | 902 | else if (! NILP (tem1)) |
| 879 | SET_PT_BOTH (clip_to_bounds (BEGV, ex->point.charpos, ZV), | 903 | { |
| 880 | clip_to_bounds (BEGV_BYTE, ex->point.bytepos, ZV_BYTE)); | 904 | tem = intern ("deactivate-mark-hook"); |
| 881 | unchain_marker (&ex->point); | 905 | Frun_hooks (1, &tem); |
| 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 | } | ||
| 919 | } | 906 | } |
| 920 | 907 | ||
| 921 | xfree (ex); | 908 | /* If buffer was visible in a window, and a different window was |
| 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 | ||