aboutsummaryrefslogtreecommitdiffstats
path: root/src/editfns.c
diff options
context:
space:
mode:
authorDmitry Antipov2012-07-27 11:51:52 +0400
committerDmitry Antipov2012-07-27 11:51:52 +0400
commiteeaea515623db982d4e7d453711e6f0fad9c08d8 (patch)
tree6c4f5398509d735e85151d480c8ba4756c1e5ec5 /src/editfns.c
parent073c88c22c0064b60ec57b6dadef9d3a4736e6b5 (diff)
downloademacs-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.c174
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
826Lisp_Object 825Lisp_Object
827save_excursion_save (void) 826save_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
857Lisp_Object 838Lisp_Object
858save_excursion_restore (Lisp_Object obj) 839save_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