Mercurial > hg > xemacs-beta
comparison src/fns.c @ 851:e7ee5f8bde58
[xemacs-hg @ 2002-05-23 11:46:08 by ben]
fix for raymond toy's crash, alloca crashes, some recover-session improvements
files.el: Recover-session improvements: Only show session files where some
files can actually be recovered, and show in chronological order.
subr.el, menubar-items.el: As promised to rms, the functionality in
truncate-string-with-continuation-dots has been merged into
truncate-string-to-width. Change callers in menubar-items.el.
select.el: Document some of these funs better. Fix problem where we were
doing own-clipboard twice.
Makefile.in.in: Add alloca.o. Ensure that alloca.s doesn't compile into alloca.o,
but allocax.o (not that it's currently used or anything.)
EmacsFrame.c, abbrev.c, alloc.c, alloca.c, callint.c, callproc.c, config.h.in, device-msw.c, device-x.c, dired.c, doc.c, editfns.c, emacs.c, emodules.c, eval.c, event-Xt.c, event-msw.c, event-stream.c, file-coding.c, fileio.c, filelock.c, fns.c, glyphs-gtk.c, glyphs-msw.c, glyphs-x.c, gui-x.c, input-method-xlib.c, intl-win32.c, lisp.h, lread.c, menubar-gtk.c, menubar-msw.c, menubar.c, mule-wnnfns.c, nt.c, objects-msw.c, process-nt.c, realpath.c, redisplay-gtk.c, redisplay-output.c, redisplay-x.c, redisplay.c, search.c, select-msw.c, sysdep.c, syswindows.h, text.c, text.h, ui-byhand.c: Fix Raymond Toy's crash. Repeat to self: 2^21 - 1 is NOT the
same as (2 << 21) - 1.
Fix crashes due to excessive alloca(). replace alloca() with
ALLOCA(), which calls the C alloca() [which uses xmalloc()]
when the size is too big. Insert in various places calls to
try to flush the C alloca() stored info if there is any.
Add MALLOC_OR_ALLOCA(), for places that expect to be alloca()ing
large blocks. This xmalloc()s when too large and records an
unwind-protect to free -- relying on the caller to unbind_to()
elsewhere in the function. Use it in concat().
Use MALLOC instead of ALLOCA in select-msw.c.
xemacs.mak: Add alloca.o.
author | ben |
---|---|
date | Thu, 23 May 2002 11:46:46 +0000 |
parents | 6728e641994e |
children | 2b6fa2618f76 |
comparison
equal
deleted
inserted
replaced
850:f915ad7befaf | 851:e7ee5f8bde58 |
---|---|
615 Lisp_Object prev; | 615 Lisp_Object prev; |
616 struct merge_string_extents_struct *args_mse = 0; | 616 struct merge_string_extents_struct *args_mse = 0; |
617 Intbyte *string_result = 0; | 617 Intbyte *string_result = 0; |
618 Intbyte *string_result_ptr = 0; | 618 Intbyte *string_result_ptr = 0; |
619 struct gcpro gcpro1; | 619 struct gcpro gcpro1; |
620 int sdep = specpdl_depth (); | |
620 | 621 |
621 /* The modus operandi in Emacs is "caller gc-protects args". | 622 /* The modus operandi in Emacs is "caller gc-protects args". |
622 However, concat is called many times in Emacs on freshly | 623 However, concat is called many times in Emacs on freshly |
623 created stuff. So we help those callers out by protecting | 624 created stuff. So we help those callers out by protecting |
624 the args ourselves to save them a lot of temporary-variable | 625 the args ourselves to save them a lot of temporary-variable |
697 | 698 |
698 switch (target_type) | 699 switch (target_type) |
699 { | 700 { |
700 case c_cons: | 701 case c_cons: |
701 if (total_length == 0) | 702 if (total_length == 0) |
702 /* In append, if all but last arg are nil, return last arg */ | 703 { |
703 RETURN_UNGCPRO (last_tail); | 704 unbind_to (sdep); |
705 /* In append, if all but last arg are nil, return last arg */ | |
706 RETURN_UNGCPRO (last_tail); | |
707 } | |
704 val = Fmake_list (make_int (total_length), Qnil); | 708 val = Fmake_list (make_int (total_length), Qnil); |
705 break; | 709 break; |
706 case c_vector: | 710 case c_vector: |
707 val = make_vector (total_length, Qnil); | 711 val = make_vector (total_length, Qnil); |
708 break; | 712 break; |
718 to the place where the substitution is called for in order | 722 to the place where the substitution is called for in order |
719 to find the place to change, and may have to do some | 723 to find the place to change, and may have to do some |
720 realloc()ing in order to make the char fit properly. | 724 realloc()ing in order to make the char fit properly. |
721 O(N^2) yuckage. */ | 725 O(N^2) yuckage. */ |
722 val = Qnil; | 726 val = Qnil; |
723 string_result = (Intbyte *) alloca (total_length * MAX_EMCHAR_LEN); | 727 string_result = |
728 (Intbyte *) MALLOC_OR_ALLOCA (total_length * MAX_EMCHAR_LEN); | |
724 string_result_ptr = string_result; | 729 string_result_ptr = string_result; |
725 break; | 730 break; |
726 default: | 731 default: |
727 val = Qnil; | 732 val = Qnil; |
728 abort (); | 733 abort (); |
836 } | 841 } |
837 | 842 |
838 if (!NILP (prev)) | 843 if (!NILP (prev)) |
839 XCDR (prev) = last_tail; | 844 XCDR (prev) = last_tail; |
840 | 845 |
846 unbind_to (sdep); | |
841 RETURN_UNGCPRO (val); | 847 RETURN_UNGCPRO (val); |
842 } | 848 } |
843 | 849 |
844 DEFUN ("copy-alist", Fcopy_alist, 1, 1, 0, /* | 850 DEFUN ("copy-alist", Fcopy_alist, 1, 1, 0, /* |
845 Return a copy of ALIST. | 851 Return a copy of ALIST. |
3098 `vals' array. By a stroke of luck, `vals' is exactly large | 3104 `vals' array. By a stroke of luck, `vals' is exactly large |
3099 enough to hold the elts left to be traversed as well as the | 3105 enough to hold the elts left to be traversed as well as the |
3100 results computed so far. | 3106 results computed so far. |
3101 | 3107 |
3102 if (vals == 0) we don't have any free space available and | 3108 if (vals == 0) we don't have any free space available and |
3103 don't want to eat up any more stack with alloca(). | 3109 don't want to eat up any more stack with ALLOCA (). |
3104 So we use EXTERNAL_LIST_LOOP_3_NO_DECLARE and GCPRO the tail. */ | 3110 So we use EXTERNAL_LIST_LOOP_3_NO_DECLARE and GCPRO the tail. */ |
3105 | 3111 |
3106 if (vals) | 3112 if (vals) |
3107 { | 3113 { |
3108 Lisp_Object *val = vals; | 3114 Lisp_Object *val = vals; |
3754 } | 3760 } |
3755 #undef ADVANCE_INPUT | 3761 #undef ADVANCE_INPUT |
3756 #undef ADVANCE_INPUT_IGNORE_NONBASE64 | 3762 #undef ADVANCE_INPUT_IGNORE_NONBASE64 |
3757 #undef STORE_BYTE | 3763 #undef STORE_BYTE |
3758 | 3764 |
3759 static Lisp_Object | |
3760 free_malloced_ptr (Lisp_Object unwind_obj) | |
3761 { | |
3762 void *ptr = (void *)get_opaque_ptr (unwind_obj); | |
3763 xfree (ptr); | |
3764 free_opaque_ptr (unwind_obj); | |
3765 return Qnil; | |
3766 } | |
3767 | |
3768 /* Don't use alloca for regions larger than this, lest we overflow | |
3769 the stack. */ | |
3770 #define MAX_ALLOCA 65536 | |
3771 | |
3772 /* We need to setup proper unwinding, because there is a number of | |
3773 ways these functions can blow up, and we don't want to have memory | |
3774 leaks in those cases. */ | |
3775 #define XMALLOC_OR_ALLOCA(ptr, len, type) do { \ | |
3776 Elemcount XOA_len = (len); \ | |
3777 if (XOA_len > MAX_ALLOCA) \ | |
3778 { \ | |
3779 ptr = xnew_array (type, XOA_len); \ | |
3780 record_unwind_protect (free_malloced_ptr, \ | |
3781 make_opaque_ptr ((void *)ptr)); \ | |
3782 } \ | |
3783 else \ | |
3784 ptr = alloca_array (type, XOA_len); \ | |
3785 } while (0) | |
3786 | |
3787 #define XMALLOC_UNBIND(ptr, len, speccount) do { \ | |
3788 if ((len) > MAX_ALLOCA) \ | |
3789 unbind_to (speccount); \ | |
3790 } while (0) | |
3791 | |
3792 DEFUN ("base64-encode-region", Fbase64_encode_region, 2, 3, "r", /* | 3765 DEFUN ("base64-encode-region", Fbase64_encode_region, 2, 3, "r", /* |
3793 Base64-encode the region between START and END. | 3766 Base64-encode the region between START and END. |
3794 Return the length of the encoded text. | 3767 Return the length of the encoded text. |
3795 Optional third argument NO-LINE-BREAK means do not break long lines | 3768 Optional third argument NO-LINE-BREAK means do not break long lines |
3796 into shorter lines. | 3769 into shorter lines. |
3801 Bytebpos encoded_length; | 3774 Bytebpos encoded_length; |
3802 Charcount allength, length; | 3775 Charcount allength, length; |
3803 struct buffer *buf = current_buffer; | 3776 struct buffer *buf = current_buffer; |
3804 Charbpos begv, zv, old_pt = BUF_PT (buf); | 3777 Charbpos begv, zv, old_pt = BUF_PT (buf); |
3805 Lisp_Object input; | 3778 Lisp_Object input; |
3806 int speccount = specpdl_depth(); | 3779 int speccount = specpdl_depth (); |
3807 | 3780 |
3808 get_buffer_range_char (buf, start, end, &begv, &zv, 0); | 3781 get_buffer_range_char (buf, start, end, &begv, &zv, 0); |
3809 barf_if_buffer_read_only (buf, begv, zv); | 3782 barf_if_buffer_read_only (buf, begv, zv); |
3810 | 3783 |
3811 /* We need to allocate enough room for encoding the text. | 3784 /* We need to allocate enough room for encoding the text. |
3816 allength += allength / MIME_LINE_LENGTH + 1 + 6; | 3789 allength += allength / MIME_LINE_LENGTH + 1 + 6; |
3817 | 3790 |
3818 input = make_lisp_buffer_input_stream (buf, begv, zv, 0); | 3791 input = make_lisp_buffer_input_stream (buf, begv, zv, 0); |
3819 /* We needn't multiply allength with MAX_EMCHAR_LEN because all the | 3792 /* We needn't multiply allength with MAX_EMCHAR_LEN because all the |
3820 base64 characters will be single-byte. */ | 3793 base64 characters will be single-byte. */ |
3821 XMALLOC_OR_ALLOCA (encoded, allength, Intbyte); | 3794 encoded = (Intbyte *) MALLOC_OR_ALLOCA (allength); |
3822 encoded_length = base64_encode_1 (XLSTREAM (input), encoded, | 3795 encoded_length = base64_encode_1 (XLSTREAM (input), encoded, |
3823 NILP (no_line_break)); | 3796 NILP (no_line_break)); |
3824 if (encoded_length > allength) | 3797 if (encoded_length > allength) |
3825 abort (); | 3798 abort (); |
3826 Lstream_delete (XLSTREAM (input)); | 3799 Lstream_delete (XLSTREAM (input)); |
3827 | 3800 |
3828 /* Now we have encoded the region, so we insert the new contents | 3801 /* Now we have encoded the region, so we insert the new contents |
3829 and delete the old. (Insert first in order to preserve markers.) */ | 3802 and delete the old. (Insert first in order to preserve markers.) */ |
3830 buffer_insert_raw_string_1 (buf, begv, encoded, encoded_length, 0); | 3803 buffer_insert_raw_string_1 (buf, begv, encoded, encoded_length, 0); |
3831 XMALLOC_UNBIND (encoded, allength, speccount); | 3804 unbind_to (speccount); |
3832 buffer_delete_range (buf, begv + encoded_length, zv + encoded_length, 0); | 3805 buffer_delete_range (buf, begv + encoded_length, zv + encoded_length, 0); |
3833 | 3806 |
3834 /* Simulate FSF Emacs implementation of this function: if point was | 3807 /* Simulate FSF Emacs implementation of this function: if point was |
3835 in the region, place it at the beginning. */ | 3808 in the region, place it at the beginning. */ |
3836 if (old_pt >= begv && old_pt < zv) | 3809 if (old_pt >= begv && old_pt < zv) |
3858 length = string_char_length (string); | 3831 length = string_char_length (string); |
3859 allength = length + length/3 + 1; | 3832 allength = length + length/3 + 1; |
3860 allength += allength / MIME_LINE_LENGTH + 1 + 6; | 3833 allength += allength / MIME_LINE_LENGTH + 1 + 6; |
3861 | 3834 |
3862 input = make_lisp_string_input_stream (string, 0, -1); | 3835 input = make_lisp_string_input_stream (string, 0, -1); |
3863 XMALLOC_OR_ALLOCA (encoded, allength, Intbyte); | 3836 encoded = (Intbyte *) MALLOC_OR_ALLOCA (allength); |
3864 encoded_length = base64_encode_1 (XLSTREAM (input), encoded, | 3837 encoded_length = base64_encode_1 (XLSTREAM (input), encoded, |
3865 NILP (no_line_break)); | 3838 NILP (no_line_break)); |
3866 if (encoded_length > allength) | 3839 if (encoded_length > allength) |
3867 abort (); | 3840 abort (); |
3868 Lstream_delete (XLSTREAM (input)); | 3841 Lstream_delete (XLSTREAM (input)); |
3869 result = make_string (encoded, encoded_length); | 3842 result = make_string (encoded, encoded_length); |
3870 XMALLOC_UNBIND (encoded, allength, speccount); | 3843 unbind_to (speccount); |
3871 return result; | 3844 return result; |
3872 } | 3845 } |
3873 | 3846 |
3874 DEFUN ("base64-decode-region", Fbase64_decode_region, 2, 2, "r", /* | 3847 DEFUN ("base64-decode-region", Fbase64_decode_region, 2, 2, "r", /* |
3875 Base64-decode the region between START and END. | 3848 Base64-decode the region between START and END. |
3892 | 3865 |
3893 length = zv - begv; | 3866 length = zv - begv; |
3894 | 3867 |
3895 input = make_lisp_buffer_input_stream (buf, begv, zv, 0); | 3868 input = make_lisp_buffer_input_stream (buf, begv, zv, 0); |
3896 /* We need to allocate enough room for decoding the text. */ | 3869 /* We need to allocate enough room for decoding the text. */ |
3897 XMALLOC_OR_ALLOCA (decoded, length * MAX_EMCHAR_LEN, Intbyte); | 3870 decoded = (Intbyte *) MALLOC_OR_ALLOCA (length * MAX_EMCHAR_LEN); |
3898 decoded_length = base64_decode_1 (XLSTREAM (input), decoded, &cc_decoded_length); | 3871 decoded_length = base64_decode_1 (XLSTREAM (input), decoded, &cc_decoded_length); |
3899 if (decoded_length > length * MAX_EMCHAR_LEN) | 3872 if (decoded_length > length * MAX_EMCHAR_LEN) |
3900 abort (); | 3873 abort (); |
3901 Lstream_delete (XLSTREAM (input)); | 3874 Lstream_delete (XLSTREAM (input)); |
3902 | 3875 |
3903 /* Now we have decoded the region, so we insert the new contents | 3876 /* Now we have decoded the region, so we insert the new contents |
3904 and delete the old. (Insert first in order to preserve markers.) */ | 3877 and delete the old. (Insert first in order to preserve markers.) */ |
3905 BUF_SET_PT (buf, begv); | 3878 BUF_SET_PT (buf, begv); |
3906 buffer_insert_raw_string_1 (buf, begv, decoded, decoded_length, 0); | 3879 buffer_insert_raw_string_1 (buf, begv, decoded, decoded_length, 0); |
3907 XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN, speccount); | 3880 unbind_to (speccount); |
3908 buffer_delete_range (buf, begv + cc_decoded_length, | 3881 buffer_delete_range (buf, begv + cc_decoded_length, |
3909 zv + cc_decoded_length, 0); | 3882 zv + cc_decoded_length, 0); |
3910 | 3883 |
3911 /* Simulate FSF Emacs implementation of this function: if point was | 3884 /* Simulate FSF Emacs implementation of this function: if point was |
3912 in the region, place it at the beginning. */ | 3885 in the region, place it at the beginning. */ |
3930 | 3903 |
3931 CHECK_STRING (string); | 3904 CHECK_STRING (string); |
3932 | 3905 |
3933 length = string_char_length (string); | 3906 length = string_char_length (string); |
3934 /* We need to allocate enough room for decoding the text. */ | 3907 /* We need to allocate enough room for decoding the text. */ |
3935 XMALLOC_OR_ALLOCA (decoded, length * MAX_EMCHAR_LEN, Intbyte); | 3908 decoded = (Intbyte *) MALLOC_OR_ALLOCA (length * MAX_EMCHAR_LEN); |
3936 | 3909 |
3937 input = make_lisp_string_input_stream (string, 0, -1); | 3910 input = make_lisp_string_input_stream (string, 0, -1); |
3938 decoded_length = base64_decode_1 (XLSTREAM (input), decoded, | 3911 decoded_length = base64_decode_1 (XLSTREAM (input), decoded, |
3939 &cc_decoded_length); | 3912 &cc_decoded_length); |
3940 if (decoded_length > length * MAX_EMCHAR_LEN) | 3913 if (decoded_length > length * MAX_EMCHAR_LEN) |
3941 abort (); | 3914 abort (); |
3942 Lstream_delete (XLSTREAM (input)); | 3915 Lstream_delete (XLSTREAM (input)); |
3943 | 3916 |
3944 result = make_string (decoded, decoded_length); | 3917 result = make_string (decoded, decoded_length); |
3945 XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN, speccount); | 3918 unbind_to (speccount); |
3946 return result; | 3919 return result; |
3947 } | 3920 } |
3948 | 3921 |
3949 Lisp_Object Qyes_or_no_p; | 3922 Lisp_Object Qyes_or_no_p; |
3950 | 3923 |