aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiles Bader2004-06-29 16:46:06 +0000
committerMiles Bader2004-06-29 16:46:06 +0000
commit12483a9413619e286efc673a2b277d85cebf3b0c (patch)
treed489e0fa758c0d51d792d42140cbeafa4aede31b /src
parentc786a8ae1c5e84d0f0903d516dd0fc190dc1193c (diff)
parent619b6adbd2b96accbbf18051bf69149a029557ee (diff)
downloademacs-12483a9413619e286efc673a2b277d85cebf3b0c.tar.gz
emacs-12483a9413619e286efc673a2b277d85cebf3b0c.zip
Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-17
Merge from emacs--cvs-trunk--0 Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-417 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-419 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-420 Tweak permissions * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-421 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-430 Update from CVS
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog128
-rw-r--r--src/alloc.c56
-rw-r--r--src/data.c21
-rw-r--r--src/doc.c2
-rw-r--r--src/editfns.c70
-rw-r--r--src/emacs.c20
-rw-r--r--src/fns.c98
-rw-r--r--src/gtkutil.c52
-rw-r--r--src/keymap.c6
-rw-r--r--src/lisp.h64
-rw-r--r--src/macterm.c108
-rw-r--r--src/print.c2
-rw-r--r--src/search.c125
-rw-r--r--src/w32fns.c25
-rw-r--r--src/xdisp.c5
15 files changed, 539 insertions, 243 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 00822d9d277..60b8d5da63d 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,131 @@
12004-06-29 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
2
3 * macterm.c (do_window_activate, do_window_deactivate): Remove.
4 (XTread_socket): Send mouse button events to the toolbox
5 dispatcher even when the mouse is grabbed. Don't process window
6 activate events for non-Emacs windows. Replace function calls to
7 do_window_activate and do_window_deactivate with their contents.
8 Reset mouse grabbing status when a window is deactivated.
9
102004-06-29 Steven Tamm <steventamm@mac.com>
11
12 * macterm.c (mac_get_emulated_btn)
13 (mac_event_to_emacs_modifiers): Fix emulated mouse button
14 support to correctly mask out modifiers.
15
162004-06-29 David Kastrup <dak@gnu.org>
17
18 * search.c (Fset_match_data): Allow buffer before end of list
19 which can happen if set-match-data is using a pre-consed list.
20
212004-06-28 Steven Tamm <steventamm@mac.com>
22
23 * macterm.c (XTread_socket): Correctly set the frame position
24 after the window is moved.
25
262004-06-28 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
27
28 * gtkutil.c (xg_get_image_for_pixmap): Call g_object_unref on
29 gpix and gmask just before return to avoid memory leak.
30 (xg_get_image_for_pixmap): Add workaround for monochrome displays
31 so insensitive and activated icons look ok.
32
332004-06-27 Jason Rumney <jasonr@gnu.org>
34
35 * w32fns.c (file_dialog_callback): Disable edit control if set
36 to directories only on CDN_INITDONE message.
37 (Fx_file_dialog): Default to directories only when prompt starts
38 with "Dired".
39
402004-06-25 Kim F. Storm <storm@cua.dk>
41
42 * alloc.c (allocate_misc): Update total_free_markers.
43 (free_misc): New function.
44 (safe_alloca_unwind, free_marker): Use it.
45
46 * lisp.h (free_misc): Add prototype.
47
48 * fns.c (Fmapconcat, Fmapcar): Remove superfluous GCPROs.
49
502004-06-24 Richard M. Stallman <rms@gnu.org>
51
52 * emacs.c (Vsignal_USR1_hook, Vsignal_USR2_hook): Definitions deleted.
53 (syms_of_emacs): Lisp variables deleted.
54
552004-06-23 David Kastrup <dak@gnu.org>
56
57 * search.c (Freplace_match): Adjust the match-data more thoroughly
58 when replacing strings in the buffer.
59 (Fmatch_data): When INTEGERS is non-nil and the last match was in
60 a buffer, add the buffer as last element to the match data.
61 (Fset_match_data): If an additional element of the match-data is a
62 buffer, restore it to last_thing_searched.
63 (save_search_regs): Save last_thing_searched as part of the match
64 data.
65 (restore_match_data): Restore it again.
66
672004-06-23 Luc Teirlinck <teirllm@auburn.edu>
68
69 * keymap.c (Ftext_char_description): Doc fix.
70 * doc.c (Fsnarf_documentation): Doc fix.
71
722004-06-22 Kim F. Storm <storm@cua.dk>
73
74 * fns.c (Fmapcar, Fmapconcat): GCPRO the args array.
75
76 * lisp.h (struct Lisp_Save_Value): New member dogc.
77 (SAFE_ALLOCA_LISP): Change second arg to number of elements.
78 Set dogc member in Lisp_Save_Value object so it will be GC'ed.
79 (SAFE_FREE_LISP): New macro.
80
81 * alloc.c (safe_alloca_unwind): Clear dogc and pointer members.
82 (make_save_value): Init new dogc member.
83 (mark_object): Mark Lisp_Save_Value pointer array if dogc is set.
84
85 * fns.c (Fmapconcat, Fmapcar): Use new SAFE_ALLOCA_LISP and
86 SAFE_FREE_LISP macros.
87
882004-06-22 Kim F. Storm <storm@cua.dk>
89
90 * lisp.h (SAFE_ALLOCA_LISP): New macro to allocate Lisp_Objects.
91 Temporarily inhibits GC if memory is xmalloc'ed, as the Lisp_Objects
92 in that memory area are unknown to GC. Add comments.
93
94 * fns.c (Fmapconcat, Fmapcar): Use SAFE_ALLOCA_LISP.
95
962004-06-21 Kim F. Storm <storm@cua.dk>
97
98 * lisp.h (MAX_ALLOCA): Define here.
99 (safe_alloca_unwind): Add prototype.
100 (USE_SAFE_ALLOCA, SAFE_ALLOCA, SAFE_FREE): New macros.
101
102 * alloc.c (safe_alloca_unwind): New function.
103
104 * casefiddle.c (casify_object): Use SAFE_ALLOCA.
105
106 * charset.c (Fstring): Use SAFE_ALLOCA.
107
108 * coding.c (MAX_ALLOCA): Remove define.
109
110 * data.c (MAX_ALLOCA): Remove define.
111 (Faset): Use SAFE_ALLOCA.
112
113 * editfns.c (Fformat, Ftranspose_regions): Use SAFE_ALLOCA.
114
115 * fns.c (string_make_multibyte, string_to_multibyte)
116 (string_make_unibyte, Fmapconcat, Fmapcar): Use SAFE_ALLOCA.
117 (MAX_ALLOCA): Remove define.
118 (Fbase64_encode_region, Fbase64_encode_string)
119 (Fbase64_decode_region, Fbase64_decode_string): Use SAFE_ALLOCA.
120 (Fbase64_encode_region, Fbase64_encode_string): Fix potential
121 memory leak if encoding fails.
122
123 * xdisp.c (add_to_log): Use SAFE_ALLOCA.
124
1252004-06-21 Eli Zaretskii <eliz@gnu.org>
126
127 * print.c (Fwith_output_to_temp_buffer): Doc fix.
128
12004-06-20 Richard M. Stallman <rms@gnu.org> 1292004-06-20 Richard M. Stallman <rms@gnu.org>
2 130
3 * xfaces.c (Finternal_copy_lisp_face): Small cleanup; doc fix. 131 * xfaces.c (Finternal_copy_lisp_face): Small cleanup; doc fix.
diff --git a/src/alloc.c b/src/alloc.c
index ea7886dd4dc..994dc21079f 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -579,6 +579,22 @@ xstrdup (s)
579} 579}
580 580
581 581
582/* Unwind for SAFE_ALLOCA */
583
584Lisp_Object
585safe_alloca_unwind (arg)
586 Lisp_Object arg;
587{
588 register struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
589
590 p->dogc = 0;
591 xfree (p->pointer);
592 p->pointer = 0;
593 free_misc (arg);
594 return Qnil;
595}
596
597
582/* Like malloc but used for allocating Lisp data. NBYTES is the 598/* Like malloc but used for allocating Lisp data. NBYTES is the
583 number of bytes to allocate, TYPE describes the intended use of the 599 number of bytes to allocate, TYPE describes the intended use of the
584 allcated memory block (for strings, for conses, ...). */ 600 allcated memory block (for strings, for conses, ...). */
@@ -2863,17 +2879,32 @@ allocate_misc ()
2863 marker_block = new; 2879 marker_block = new;
2864 marker_block_index = 0; 2880 marker_block_index = 0;
2865 n_marker_blocks++; 2881 n_marker_blocks++;
2882 total_free_markers += MARKER_BLOCK_SIZE;
2866 } 2883 }
2867 XSETMISC (val, &marker_block->markers[marker_block_index]); 2884 XSETMISC (val, &marker_block->markers[marker_block_index]);
2868 marker_block_index++; 2885 marker_block_index++;
2869 } 2886 }
2870 2887
2888 --total_free_markers;
2871 consing_since_gc += sizeof (union Lisp_Misc); 2889 consing_since_gc += sizeof (union Lisp_Misc);
2872 misc_objects_consed++; 2890 misc_objects_consed++;
2873 XMARKER (val)->gcmarkbit = 0; 2891 XMARKER (val)->gcmarkbit = 0;
2874 return val; 2892 return val;
2875} 2893}
2876 2894
2895/* Free a Lisp_Misc object */
2896
2897void
2898free_misc (misc)
2899 Lisp_Object misc;
2900{
2901 XMISC (misc)->u_marker.type = Lisp_Misc_Free;
2902 XMISC (misc)->u_free.chain = marker_free_list;
2903 marker_free_list = XMISC (misc);
2904
2905 total_free_markers++;
2906}
2907
2877/* Return a Lisp_Misc_Save_Value object containing POINTER and 2908/* Return a Lisp_Misc_Save_Value object containing POINTER and
2878 INTEGER. This is used to package C values to call record_unwind_protect. 2909 INTEGER. This is used to package C values to call record_unwind_protect.
2879 The unwind function can get the C values back using XSAVE_VALUE. */ 2910 The unwind function can get the C values back using XSAVE_VALUE. */
@@ -2891,6 +2922,7 @@ make_save_value (pointer, integer)
2891 p = XSAVE_VALUE (val); 2922 p = XSAVE_VALUE (val);
2892 p->pointer = pointer; 2923 p->pointer = pointer;
2893 p->integer = integer; 2924 p->integer = integer;
2925 p->dogc = 0;
2894 return val; 2926 return val;
2895} 2927}
2896 2928
@@ -2919,12 +2951,7 @@ free_marker (marker)
2919 Lisp_Object marker; 2951 Lisp_Object marker;
2920{ 2952{
2921 unchain_marker (XMARKER (marker)); 2953 unchain_marker (XMARKER (marker));
2922 2954 free_misc (marker);
2923 XMISC (marker)->u_marker.type = Lisp_Misc_Free;
2924 XMISC (marker)->u_free.chain = marker_free_list;
2925 marker_free_list = XMISC (marker);
2926
2927 total_free_markers++;
2928} 2955}
2929 2956
2930 2957
@@ -4924,6 +4951,7 @@ mark_object (arg)
4924 if (XMARKER (obj)->gcmarkbit) 4951 if (XMARKER (obj)->gcmarkbit)
4925 break; 4952 break;
4926 XMARKER (obj)->gcmarkbit = 1; 4953 XMARKER (obj)->gcmarkbit = 1;
4954
4927 switch (XMISCTYPE (obj)) 4955 switch (XMISCTYPE (obj))
4928 { 4956 {
4929 case Lisp_Misc_Buffer_Local_Value: 4957 case Lisp_Misc_Buffer_Local_Value:
@@ -4948,6 +4976,8 @@ mark_object (arg)
4948 /* DO NOT mark thru the marker's chain. 4976 /* DO NOT mark thru the marker's chain.
4949 The buffer's markers chain does not preserve markers from gc; 4977 The buffer's markers chain does not preserve markers from gc;
4950 instead, markers are removed from the chain when freed by gc. */ 4978 instead, markers are removed from the chain when freed by gc. */
4979 break;
4980
4951 case Lisp_Misc_Intfwd: 4981 case Lisp_Misc_Intfwd:
4952 case Lisp_Misc_Boolfwd: 4982 case Lisp_Misc_Boolfwd:
4953 case Lisp_Misc_Objfwd: 4983 case Lisp_Misc_Objfwd:
@@ -4957,7 +4987,21 @@ mark_object (arg)
4957 since all markable slots in current buffer marked anyway. */ 4987 since all markable slots in current buffer marked anyway. */
4958 /* Don't need to do Lisp_Objfwd, since the places they point 4988 /* Don't need to do Lisp_Objfwd, since the places they point
4959 are protected with staticpro. */ 4989 are protected with staticpro. */
4990 break;
4991
4960 case Lisp_Misc_Save_Value: 4992 case Lisp_Misc_Save_Value:
4993 {
4994 register struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj);
4995 /* If DOGC is set, POINTER is the address of a memory
4996 area containing INTEGER potential Lisp_Objects. */
4997 if (ptr->dogc)
4998 {
4999 Lisp_Object *p = (Lisp_Object *) ptr->pointer;
5000 int nelt;
5001 for (nelt = ptr->integer; nelt > 0; nelt--, p++)
5002 mark_maybe_object (*p);
5003 }
5004 }
4961 break; 5005 break;
4962 5006
4963 case Lisp_Misc_Overlay: 5007 case Lisp_Misc_Overlay:
diff --git a/src/data.c b/src/data.c
index 935c4348bb7..1071107947c 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1983,11 +1983,6 @@ or a byte-code object. IDX starts at 0. */)
1983 } 1983 }
1984} 1984}
1985 1985
1986/* Don't use alloca for relocating string data larger than this, lest
1987 we overflow their stack. The value is the same as what used in
1988 fns.c for base64 handling. */
1989#define MAX_ALLOCA 16*1024
1990
1991DEFUN ("aset", Faset, Saset, 3, 3, 0, 1986DEFUN ("aset", Faset, Saset, 3, 3, 0,
1992 doc: /* Store into the element of ARRAY at index IDX the value NEWELT. 1987 doc: /* Store into the element of ARRAY at index IDX the value NEWELT.
1993Return NEWELT. ARRAY may be a vector, a string, a char-table or a 1988Return NEWELT. ARRAY may be a vector, a string, a char-table or a
@@ -2051,10 +2046,9 @@ bool-vector. IDX starts at 0. */)
2051 /* We must relocate the string data. */ 2046 /* We must relocate the string data. */
2052 int nchars = SCHARS (array); 2047 int nchars = SCHARS (array);
2053 unsigned char *str; 2048 unsigned char *str;
2049 USE_SAFE_ALLOCA;
2054 2050
2055 str = (nbytes <= MAX_ALLOCA 2051 SAFE_ALLOCA (str, unsigned char *, nbytes);
2056 ? (unsigned char *) alloca (nbytes)
2057 : (unsigned char *) xmalloc (nbytes));
2058 bcopy (SDATA (array), str, nbytes); 2052 bcopy (SDATA (array), str, nbytes);
2059 allocate_string_data (XSTRING (array), nchars, 2053 allocate_string_data (XSTRING (array), nchars,
2060 nbytes + new_bytes - prev_bytes); 2054 nbytes + new_bytes - prev_bytes);
@@ -2062,8 +2056,7 @@ bool-vector. IDX starts at 0. */)
2062 p1 = SDATA (array) + idxval_byte; 2056 p1 = SDATA (array) + idxval_byte;
2063 bcopy (str + idxval_byte + prev_bytes, p1 + new_bytes, 2057 bcopy (str + idxval_byte + prev_bytes, p1 + new_bytes,
2064 nbytes - (idxval_byte + prev_bytes)); 2058 nbytes - (idxval_byte + prev_bytes));
2065 if (nbytes > MAX_ALLOCA) 2059 SAFE_FREE (nbytes);
2066 xfree (str);
2067 clear_string_char_byte_cache (); 2060 clear_string_char_byte_cache ();
2068 } 2061 }
2069 while (new_bytes--) 2062 while (new_bytes--)
@@ -2086,14 +2079,13 @@ bool-vector. IDX starts at 0. */)
2086 unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1; 2079 unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1;
2087 unsigned char *origstr = SDATA (array), *str; 2080 unsigned char *origstr = SDATA (array), *str;
2088 int nchars, nbytes; 2081 int nchars, nbytes;
2082 USE_SAFE_ALLOCA;
2089 2083
2090 nchars = SCHARS (array); 2084 nchars = SCHARS (array);
2091 nbytes = idxval_byte = count_size_as_multibyte (origstr, idxval); 2085 nbytes = idxval_byte = count_size_as_multibyte (origstr, idxval);
2092 nbytes += count_size_as_multibyte (origstr + idxval, 2086 nbytes += count_size_as_multibyte (origstr + idxval,
2093 nchars - idxval); 2087 nchars - idxval);
2094 str = (nbytes <= MAX_ALLOCA 2088 SAFE_ALLOCA (str, unsigned char *, nbytes);
2095 ? (unsigned char *) alloca (nbytes)
2096 : (unsigned char *) xmalloc (nbytes));
2097 copy_text (SDATA (array), str, nchars, 0, 1); 2089 copy_text (SDATA (array), str, nchars, 0, 1);
2098 PARSE_MULTIBYTE_SEQ (str + idxval_byte, nbytes - idxval_byte, 2090 PARSE_MULTIBYTE_SEQ (str + idxval_byte, nbytes - idxval_byte,
2099 prev_bytes); 2091 prev_bytes);
@@ -2106,8 +2098,7 @@ bool-vector. IDX starts at 0. */)
2106 *p1++ = *p0++; 2098 *p1++ = *p0++;
2107 bcopy (str + idxval_byte + prev_bytes, p1, 2099 bcopy (str + idxval_byte + prev_bytes, p1,
2108 nbytes - (idxval_byte + prev_bytes)); 2100 nbytes - (idxval_byte + prev_bytes));
2109 if (nbytes > MAX_ALLOCA) 2101 SAFE_FREE (nbytes);
2110 xfree (str);
2111 clear_string_char_byte_cache (); 2102 clear_string_char_byte_cache ();
2112 } 2103 }
2113 } 2104 }
diff --git a/src/doc.c b/src/doc.c
index 2e66c5cea46..8c116210cda 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -570,7 +570,7 @@ records them in function and variable definitions.
570The function takes one argument, FILENAME, a string; 570The function takes one argument, FILENAME, a string;
571it specifies the file name (without a directory) of the DOC file. 571it specifies the file name (without a directory) of the DOC file.
572That file is found in `../etc' now; later, when the dumped Emacs is run, 572That file is found in `../etc' now; later, when the dumped Emacs is run,
573the same file name is found in the `data-directory'. */) 573the same file name is found in the `doc-directory'. */)
574 (filename) 574 (filename)
575 Lisp_Object filename; 575 Lisp_Object filename;
576{ 576{
diff --git a/src/editfns.c b/src/editfns.c
index 130dffa77de..9928beff678 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3381,6 +3381,7 @@ usage: (format STRING &rest OBJECTS) */)
3381 int longest_format; 3381 int longest_format;
3382 Lisp_Object val; 3382 Lisp_Object val;
3383 int arg_intervals = 0; 3383 int arg_intervals = 0;
3384 USE_SAFE_ALLOCA;
3384 3385
3385 /* discarded[I] is 1 if byte I of the format 3386 /* discarded[I] is 1 if byte I of the format
3386 string was not copied into the output. 3387 string was not copied into the output.
@@ -3429,7 +3430,7 @@ usage: (format STRING &rest OBJECTS) */)
3429 longest_format = 0; 3430 longest_format = 0;
3430 3431
3431 /* Make room in result for all the non-%-codes in the control string. */ 3432 /* Make room in result for all the non-%-codes in the control string. */
3432 total = 5 + CONVERTED_BYTE_SIZE (multibyte, args[0]); 3433 total = 5 + CONVERTED_BYTE_SIZE (multibyte, args[0]) + 1;
3433 3434
3434 /* Allocate the info and discarded tables. */ 3435 /* Allocate the info and discarded tables. */
3435 { 3436 {
@@ -3622,10 +3623,7 @@ usage: (format STRING &rest OBJECTS) */)
3622 3623
3623 /* Allocate the space for the result. 3624 /* Allocate the space for the result.
3624 Note that TOTAL is an overestimate. */ 3625 Note that TOTAL is an overestimate. */
3625 if (total < 1000) 3626 SAFE_ALLOCA (buf, char *, total);
3626 buf = (char *) alloca (total + 1);
3627 else
3628 buf = (char *) xmalloc (total + 1);
3629 3627
3630 p = buf; 3628 p = buf;
3631 nchars = 0; 3629 nchars = 0;
@@ -3758,7 +3756,7 @@ usage: (format STRING &rest OBJECTS) */)
3758 maybe_combine_byte = 1; 3756 maybe_combine_byte = 1;
3759 this_nchars = strlen (p); 3757 this_nchars = strlen (p);
3760 if (multibyte) 3758 if (multibyte)
3761 p += str_to_multibyte (p, buf + total - p, this_nchars); 3759 p += str_to_multibyte (p, buf + total - 1 - p, this_nchars);
3762 else 3760 else
3763 p += this_nchars; 3761 p += this_nchars;
3764 nchars += this_nchars; 3762 nchars += this_nchars;
@@ -3795,7 +3793,7 @@ usage: (format STRING &rest OBJECTS) */)
3795 *p++ = *format++, nchars++; 3793 *p++ = *format++, nchars++;
3796 } 3794 }
3797 3795
3798 if (p > buf + total + 1) 3796 if (p > buf + total)
3799 abort (); 3797 abort ();
3800 3798
3801 if (maybe_combine_byte) 3799 if (maybe_combine_byte)
@@ -3803,8 +3801,7 @@ usage: (format STRING &rest OBJECTS) */)
3803 val = make_specified_string (buf, nchars, p - buf, multibyte); 3801 val = make_specified_string (buf, nchars, p - buf, multibyte);
3804 3802
3805 /* If we allocated BUF with malloc, free it too. */ 3803 /* If we allocated BUF with malloc, free it too. */
3806 if (total >= 1000) 3804 SAFE_FREE (total);
3807 xfree (buf);
3808 3805
3809 /* If the format string has text properties, or any of the string 3806 /* If the format string has text properties, or any of the string
3810 arguments has text properties, set up text properties of the 3807 arguments has text properties, set up text properties of the
@@ -4173,12 +4170,9 @@ Transposing beyond buffer boundaries is an error. */)
4173 /* First region smaller than second. */ 4170 /* First region smaller than second. */
4174 if (len1_byte < len2_byte) 4171 if (len1_byte < len2_byte)
4175 { 4172 {
4176 /* We use alloca only if it is small, 4173 USE_SAFE_ALLOCA;
4177 because we want to avoid stack overflow. */ 4174
4178 if (len2_byte > 20000) 4175 SAFE_ALLOCA (temp, unsigned char *, len2_byte);
4179 temp = (unsigned char *) xmalloc (len2_byte);
4180 else
4181 temp = (unsigned char *) alloca (len2_byte);
4182 4176
4183 /* Don't precompute these addresses. We have to compute them 4177 /* Don't precompute these addresses. We have to compute them
4184 at the last minute, because the relocating allocator might 4178 at the last minute, because the relocating allocator might
@@ -4189,23 +4183,20 @@ Transposing beyond buffer boundaries is an error. */)
4189 bcopy (start2_addr, temp, len2_byte); 4183 bcopy (start2_addr, temp, len2_byte);
4190 bcopy (start1_addr, start1_addr + len2_byte, len1_byte); 4184 bcopy (start1_addr, start1_addr + len2_byte, len1_byte);
4191 bcopy (temp, start1_addr, len2_byte); 4185 bcopy (temp, start1_addr, len2_byte);
4192 if (len2_byte > 20000) 4186 SAFE_FREE (len2_byte);
4193 xfree (temp);
4194 } 4187 }
4195 else 4188 else
4196 /* First region not smaller than second. */ 4189 /* First region not smaller than second. */
4197 { 4190 {
4198 if (len1_byte > 20000) 4191 USE_SAFE_ALLOCA;
4199 temp = (unsigned char *) xmalloc (len1_byte); 4192
4200 else 4193 SAFE_ALLOCA (temp, unsigned char *, len1_byte);
4201 temp = (unsigned char *) alloca (len1_byte);
4202 start1_addr = BYTE_POS_ADDR (start1_byte); 4194 start1_addr = BYTE_POS_ADDR (start1_byte);
4203 start2_addr = BYTE_POS_ADDR (start2_byte); 4195 start2_addr = BYTE_POS_ADDR (start2_byte);
4204 bcopy (start1_addr, temp, len1_byte); 4196 bcopy (start1_addr, temp, len1_byte);
4205 bcopy (start2_addr, start1_addr, len2_byte); 4197 bcopy (start2_addr, start1_addr, len2_byte);
4206 bcopy (temp, start1_addr + len2_byte, len1_byte); 4198 bcopy (temp, start1_addr + len2_byte, len1_byte);
4207 if (len1_byte > 20000) 4199 SAFE_FREE (len1_byte);
4208 xfree (temp);
4209 } 4200 }
4210 graft_intervals_into_buffer (tmp_interval1, start1 + len2, 4201 graft_intervals_into_buffer (tmp_interval1, start1 + len2,
4211 len1, current_buffer, 0); 4202 len1, current_buffer, 0);
@@ -4222,6 +4213,8 @@ Transposing beyond buffer boundaries is an error. */)
4222 if (len1_byte == len2_byte) 4213 if (len1_byte == len2_byte)
4223 /* Regions are same size, though, how nice. */ 4214 /* Regions are same size, though, how nice. */
4224 { 4215 {
4216 USE_SAFE_ALLOCA;
4217
4225 modify_region (current_buffer, start1, end1); 4218 modify_region (current_buffer, start1, end1);
4226 modify_region (current_buffer, start2, end2); 4219 modify_region (current_buffer, start2, end2);
4227 record_change (start1, len1); 4220 record_change (start1, len1);
@@ -4233,17 +4226,14 @@ Transposing beyond buffer boundaries is an error. */)
4233 Fset_text_properties (make_number (start2), make_number (end2), 4226 Fset_text_properties (make_number (start2), make_number (end2),
4234 Qnil, Qnil); 4227 Qnil, Qnil);
4235 4228
4236 if (len1_byte > 20000) 4229 SAFE_ALLOCA (temp, unsigned char *, len1_byte);
4237 temp = (unsigned char *) xmalloc (len1_byte);
4238 else
4239 temp = (unsigned char *) alloca (len1_byte);
4240 start1_addr = BYTE_POS_ADDR (start1_byte); 4230 start1_addr = BYTE_POS_ADDR (start1_byte);
4241 start2_addr = BYTE_POS_ADDR (start2_byte); 4231 start2_addr = BYTE_POS_ADDR (start2_byte);
4242 bcopy (start1_addr, temp, len1_byte); 4232 bcopy (start1_addr, temp, len1_byte);
4243 bcopy (start2_addr, start1_addr, len2_byte); 4233 bcopy (start2_addr, start1_addr, len2_byte);
4244 bcopy (temp, start2_addr, len1_byte); 4234 bcopy (temp, start2_addr, len1_byte);
4245 if (len1_byte > 20000) 4235 SAFE_FREE (len1_byte);
4246 xfree (temp); 4236
4247 graft_intervals_into_buffer (tmp_interval1, start2, 4237 graft_intervals_into_buffer (tmp_interval1, start2,
4248 len1, current_buffer, 0); 4238 len1, current_buffer, 0);
4249 graft_intervals_into_buffer (tmp_interval2, start1, 4239 graft_intervals_into_buffer (tmp_interval2, start1,
@@ -4253,6 +4243,8 @@ Transposing beyond buffer boundaries is an error. */)
4253 else if (len1_byte < len2_byte) /* Second region larger than first */ 4243 else if (len1_byte < len2_byte) /* Second region larger than first */
4254 /* Non-adjacent & unequal size, area between must also be shifted. */ 4244 /* Non-adjacent & unequal size, area between must also be shifted. */
4255 { 4245 {
4246 USE_SAFE_ALLOCA;
4247
4256 modify_region (current_buffer, start1, end2); 4248 modify_region (current_buffer, start1, end2);
4257 record_change (start1, (end2 - start1)); 4249 record_change (start1, (end2 - start1));
4258 tmp_interval1 = copy_intervals (cur_intv, start1, len1); 4250 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
@@ -4262,18 +4254,15 @@ Transposing beyond buffer boundaries is an error. */)
4262 Qnil, Qnil); 4254 Qnil, Qnil);
4263 4255
4264 /* holds region 2 */ 4256 /* holds region 2 */
4265 if (len2_byte > 20000) 4257 SAFE_ALLOCA (temp, unsigned char *, len2_byte);
4266 temp = (unsigned char *) xmalloc (len2_byte);
4267 else
4268 temp = (unsigned char *) alloca (len2_byte);
4269 start1_addr = BYTE_POS_ADDR (start1_byte); 4258 start1_addr = BYTE_POS_ADDR (start1_byte);
4270 start2_addr = BYTE_POS_ADDR (start2_byte); 4259 start2_addr = BYTE_POS_ADDR (start2_byte);
4271 bcopy (start2_addr, temp, len2_byte); 4260 bcopy (start2_addr, temp, len2_byte);
4272 bcopy (start1_addr, start1_addr + len_mid + len2_byte, len1_byte); 4261 bcopy (start1_addr, start1_addr + len_mid + len2_byte, len1_byte);
4273 safe_bcopy (start1_addr + len1_byte, start1_addr + len2_byte, len_mid); 4262 safe_bcopy (start1_addr + len1_byte, start1_addr + len2_byte, len_mid);
4274 bcopy (temp, start1_addr, len2_byte); 4263 bcopy (temp, start1_addr, len2_byte);
4275 if (len2_byte > 20000) 4264 SAFE_FREE (len2_byte);
4276 xfree (temp); 4265
4277 graft_intervals_into_buffer (tmp_interval1, end2 - len1, 4266 graft_intervals_into_buffer (tmp_interval1, end2 - len1,
4278 len1, current_buffer, 0); 4267 len1, current_buffer, 0);
4279 graft_intervals_into_buffer (tmp_interval_mid, start1 + len2, 4268 graft_intervals_into_buffer (tmp_interval_mid, start1 + len2,
@@ -4284,6 +4273,8 @@ Transposing beyond buffer boundaries is an error. */)
4284 else 4273 else
4285 /* Second region smaller than first. */ 4274 /* Second region smaller than first. */
4286 { 4275 {
4276 USE_SAFE_ALLOCA;
4277
4287 record_change (start1, (end2 - start1)); 4278 record_change (start1, (end2 - start1));
4288 modify_region (current_buffer, start1, end2); 4279 modify_region (current_buffer, start1, end2);
4289 4280
@@ -4294,18 +4285,15 @@ Transposing beyond buffer boundaries is an error. */)
4294 Qnil, Qnil); 4285 Qnil, Qnil);
4295 4286
4296 /* holds region 1 */ 4287 /* holds region 1 */
4297 if (len1_byte > 20000) 4288 SAFE_ALLOCA (temp, unsigned char *, len1_byte);
4298 temp = (unsigned char *) xmalloc (len1_byte);
4299 else
4300 temp = (unsigned char *) alloca (len1_byte);
4301 start1_addr = BYTE_POS_ADDR (start1_byte); 4289 start1_addr = BYTE_POS_ADDR (start1_byte);
4302 start2_addr = BYTE_POS_ADDR (start2_byte); 4290 start2_addr = BYTE_POS_ADDR (start2_byte);
4303 bcopy (start1_addr, temp, len1_byte); 4291 bcopy (start1_addr, temp, len1_byte);
4304 bcopy (start2_addr, start1_addr, len2_byte); 4292 bcopy (start2_addr, start1_addr, len2_byte);
4305 bcopy (start1_addr + len1_byte, start1_addr + len2_byte, len_mid); 4293 bcopy (start1_addr + len1_byte, start1_addr + len2_byte, len_mid);
4306 bcopy (temp, start1_addr + len2_byte + len_mid, len1_byte); 4294 bcopy (temp, start1_addr + len2_byte + len_mid, len1_byte);
4307 if (len1_byte > 20000) 4295 SAFE_FREE (len1_byte);
4308 xfree (temp); 4296
4309 graft_intervals_into_buffer (tmp_interval1, end2 - len1, 4297 graft_intervals_into_buffer (tmp_interval1, end2 - len1,
4310 len1, current_buffer, 0); 4298 len1, current_buffer, 0);
4311 graft_intervals_into_buffer (tmp_interval_mid, start1 + len2, 4299 graft_intervals_into_buffer (tmp_interval_mid, start1 + len2,
diff --git a/src/emacs.c b/src/emacs.c
index d348eb86d29..5b7394627ef 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -126,14 +126,6 @@ Lisp_Object Vkill_emacs_hook;
126/* An empty lisp string. To avoid having to build any other. */ 126/* An empty lisp string. To avoid having to build any other. */
127Lisp_Object empty_string; 127Lisp_Object empty_string;
128 128
129#ifdef SIGUSR1
130/* Hooks for signal USR1 and USR2 handling. */
131Lisp_Object Vsignal_USR1_hook;
132#ifdef SIGUSR2
133Lisp_Object Vsignal_USR2_hook;
134#endif
135#endif
136
137/* Search path separator. */ 129/* Search path separator. */
138Lisp_Object Vpath_separator; 130Lisp_Object Vpath_separator;
139 131
@@ -2379,18 +2371,6 @@ The hook is not run in batch mode, i.e., if `noninteractive' is non-nil. */);
2379 empty_string = build_string (""); 2371 empty_string = build_string ("");
2380 staticpro (&empty_string); 2372 staticpro (&empty_string);
2381 2373
2382#ifdef SIGUSR1
2383 DEFVAR_LISP ("signal-USR1-hook", &Vsignal_USR1_hook,
2384 doc: /* Hook to be run whenever emacs receives a USR1 signal. */);
2385 Vsignal_USR1_hook = Qnil;
2386#ifdef SIGUSR2
2387 DEFVAR_LISP ("signal-USR2-hook", &Vsignal_USR2_hook,
2388 doc: /* Hook to be run whenever emacs receives a USR2 signal. */);
2389 Vsignal_USR2_hook = Qnil;
2390#endif
2391#endif
2392
2393
2394 DEFVAR_INT ("emacs-priority", &emacs_priority, 2374 DEFVAR_INT ("emacs-priority", &emacs_priority,
2395 doc: /* Priority for Emacs to run at. 2375 doc: /* Priority for Emacs to run at.
2396This value is effective only if set before Emacs is dumped, 2376This value is effective only if set before Emacs is dumped,
diff --git a/src/fns.c b/src/fns.c
index 5e20687494c..2058fb63a4e 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -929,11 +929,14 @@ string_make_multibyte (string)
929 if (nbytes == SBYTES (string)) 929 if (nbytes == SBYTES (string))
930 return string; 930 return string;
931 931
932 buf = (unsigned char *) alloca (nbytes); 932 SAFE_ALLOCA (buf, unsigned char *, nbytes);
933 copy_text (SDATA (string), buf, SBYTES (string), 933 copy_text (SDATA (string), buf, SBYTES (string),
934 0, 1); 934 0, 1);
935 935
936 return make_multibyte_string (buf, SCHARS (string), nbytes); 936 ret = make_multibyte_string (buf, SCHARS (string), nbytes);
937 SAFE_FREE (nbytes);
938
939 return ret;
937} 940}
938 941
939 942
@@ -947,6 +950,8 @@ string_to_multibyte (string)
947{ 950{
948 unsigned char *buf; 951 unsigned char *buf;
949 int nbytes; 952 int nbytes;
953 Lisp_Object ret;
954 USE_SAFE_ALLOCA;
950 955
951 if (STRING_MULTIBYTE (string)) 956 if (STRING_MULTIBYTE (string))
952 return string; 957 return string;
@@ -957,11 +962,14 @@ string_to_multibyte (string)
957 if (nbytes == SBYTES (string)) 962 if (nbytes == SBYTES (string))
958 return make_multibyte_string (SDATA (string), nbytes, nbytes); 963 return make_multibyte_string (SDATA (string), nbytes, nbytes);
959 964
960 buf = (unsigned char *) alloca (nbytes); 965 SAFE_ALLOCA (buf, unsigned char *, nbytes);
961 bcopy (SDATA (string), buf, SBYTES (string)); 966 bcopy (SDATA (string), buf, SBYTES (string));
962 str_to_multibyte (buf, nbytes, SBYTES (string)); 967 str_to_multibyte (buf, nbytes, SBYTES (string));
963 968
964 return make_multibyte_string (buf, SCHARS (string), nbytes); 969 ret = make_multibyte_string (buf, SCHARS (string), nbytes);
970 SAFE_FREE (nbytes);
971
972 return ret;
965} 973}
966 974
967 975
@@ -971,23 +979,22 @@ Lisp_Object
971string_make_unibyte (string) 979string_make_unibyte (string)
972 Lisp_Object string; 980 Lisp_Object string;
973{ 981{
982 int nchars;
974 unsigned char *buf; 983 unsigned char *buf;
975 Lisp_Object ret; 984 Lisp_Object ret;
985 USE_SAFE_ALLOCA;
976 986
977 if (! STRING_MULTIBYTE (string)) 987 if (! STRING_MULTIBYTE (string))
978 return string; 988 return string;
979 989
980 /* We can not use alloca here, because string might be very long. 990 nchars = SCHARS (string);
981 For example when selecting megabytes of text and then pasting it to
982 another application. */
983 buf = (unsigned char *) xmalloc (SCHARS (string));
984 991
992 SAFE_ALLOCA (buf, unsigned char *, nchars);
985 copy_text (SDATA (string), buf, SBYTES (string), 993 copy_text (SDATA (string), buf, SBYTES (string),
986 1, 0); 994 1, 0);
987 995
988 ret = make_unibyte_string (buf, SCHARS (string)); 996 ret = make_unibyte_string (buf, nchars);
989 997 SAFE_FREE (nchars);
990 xfree (buf);
991 998
992 return ret; 999 return ret;
993} 1000}
@@ -2455,6 +2462,8 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string. */)
2455 register Lisp_Object *args; 2462 register Lisp_Object *args;
2456 register int i; 2463 register int i;
2457 struct gcpro gcpro1; 2464 struct gcpro gcpro1;
2465 Lisp_Object ret;
2466 USE_SAFE_ALLOCA;
2458 2467
2459 len = Flength (sequence); 2468 len = Flength (sequence);
2460 if (CHAR_TABLE_P (sequence)) 2469 if (CHAR_TABLE_P (sequence))
@@ -2463,7 +2472,7 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string. */)
2463 nargs = leni + leni - 1; 2472 nargs = leni + leni - 1;
2464 if (nargs < 0) return build_string (""); 2473 if (nargs < 0) return build_string ("");
2465 2474
2466 args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object)); 2475 SAFE_ALLOCA_LISP (args, nargs);
2467 2476
2468 GCPRO1 (separator); 2477 GCPRO1 (separator);
2469 mapcar1 (leni, args, function, sequence); 2478 mapcar1 (leni, args, function, sequence);
@@ -2475,7 +2484,10 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string. */)
2475 for (i = 1; i < nargs; i += 2) 2484 for (i = 1; i < nargs; i += 2)
2476 args[i] = separator; 2485 args[i] = separator;
2477 2486
2478 return Fconcat (nargs, args); 2487 ret = Fconcat (nargs, args);
2488 SAFE_FREE_LISP (nargs);
2489
2490 return ret;
2479} 2491}
2480 2492
2481DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0, 2493DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0,
@@ -2488,16 +2500,22 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string. */)
2488 register Lisp_Object len; 2500 register Lisp_Object len;
2489 register int leni; 2501 register int leni;
2490 register Lisp_Object *args; 2502 register Lisp_Object *args;
2503 Lisp_Object ret;
2504 USE_SAFE_ALLOCA;
2491 2505
2492 len = Flength (sequence); 2506 len = Flength (sequence);
2493 if (CHAR_TABLE_P (sequence)) 2507 if (CHAR_TABLE_P (sequence))
2494 wrong_type_argument (Qlistp, sequence); 2508 wrong_type_argument (Qlistp, sequence);
2495 leni = XFASTINT (len); 2509 leni = XFASTINT (len);
2496 args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object)); 2510
2511 SAFE_ALLOCA_LISP (args, leni);
2497 2512
2498 mapcar1 (leni, args, function, sequence); 2513 mapcar1 (leni, args, function, sequence);
2499 2514
2500 return Flist (leni, args); 2515 ret = Flist (leni, args);
2516 SAFE_FREE_LISP (leni);
2517
2518 return ret;
2501} 2519}
2502 2520
2503DEFUN ("mapc", Fmapc, Smapc, 2, 2, 0, 2521DEFUN ("mapc", Fmapc, Smapc, 2, 2, 0,
@@ -3114,10 +3132,6 @@ The data read from the system are decoded using `locale-coding-system'. */)
3114 } \ 3132 } \
3115 while (IS_BASE64_IGNORABLE (c)) 3133 while (IS_BASE64_IGNORABLE (c))
3116 3134
3117/* Don't use alloca for regions larger than this, lest we overflow
3118 their stack. */
3119#define MAX_ALLOCA 16*1024
3120
3121/* Table of characters coding the 64 values. */ 3135/* Table of characters coding the 64 values. */
3122static char base64_value_to_char[64] = 3136static char base64_value_to_char[64] =
3123{ 3137{
@@ -3183,6 +3197,7 @@ into shorter lines. */)
3183 int allength, length; 3197 int allength, length;
3184 int ibeg, iend, encoded_length; 3198 int ibeg, iend, encoded_length;
3185 int old_pos = PT; 3199 int old_pos = PT;
3200 USE_SAFE_ALLOCA;
3186 3201
3187 validate_region (&beg, &end); 3202 validate_region (&beg, &end);
3188 3203
@@ -3197,10 +3212,7 @@ into shorter lines. */)
3197 allength = length + length/3 + 1; 3212 allength = length + length/3 + 1;
3198 allength += allength / MIME_LINE_LENGTH + 1 + 6; 3213 allength += allength / MIME_LINE_LENGTH + 1 + 6;
3199 3214
3200 if (allength <= MAX_ALLOCA) 3215 SAFE_ALLOCA (encoded, char *, allength);
3201 encoded = (char *) alloca (allength);
3202 else
3203 encoded = (char *) xmalloc (allength);
3204 encoded_length = base64_encode_1 (BYTE_POS_ADDR (ibeg), encoded, length, 3216 encoded_length = base64_encode_1 (BYTE_POS_ADDR (ibeg), encoded, length,
3205 NILP (no_line_break), 3217 NILP (no_line_break),
3206 !NILP (current_buffer->enable_multibyte_characters)); 3218 !NILP (current_buffer->enable_multibyte_characters));
@@ -3210,8 +3222,7 @@ into shorter lines. */)
3210 if (encoded_length < 0) 3222 if (encoded_length < 0)
3211 { 3223 {
3212 /* The encoding wasn't possible. */ 3224 /* The encoding wasn't possible. */
3213 if (length > MAX_ALLOCA) 3225 SAFE_FREE (allength);
3214 xfree (encoded);
3215 error ("Multibyte character in data for base64 encoding"); 3226 error ("Multibyte character in data for base64 encoding");
3216 } 3227 }
3217 3228
@@ -3219,8 +3230,7 @@ into shorter lines. */)
3219 and delete the old. (Insert first in order to preserve markers.) */ 3230 and delete the old. (Insert first in order to preserve markers.) */
3220 SET_PT_BOTH (XFASTINT (beg), ibeg); 3231 SET_PT_BOTH (XFASTINT (beg), ibeg);
3221 insert (encoded, encoded_length); 3232 insert (encoded, encoded_length);
3222 if (allength > MAX_ALLOCA) 3233 SAFE_FREE (allength);
3223 xfree (encoded);
3224 del_range_byte (ibeg + encoded_length, iend + encoded_length, 1); 3234 del_range_byte (ibeg + encoded_length, iend + encoded_length, 1);
3225 3235
3226 /* If point was outside of the region, restore it exactly; else just 3236 /* If point was outside of the region, restore it exactly; else just
@@ -3246,6 +3256,7 @@ into shorter lines. */)
3246 int allength, length, encoded_length; 3256 int allength, length, encoded_length;
3247 char *encoded; 3257 char *encoded;
3248 Lisp_Object encoded_string; 3258 Lisp_Object encoded_string;
3259 USE_SAFE_ALLOCA;
3249 3260
3250 CHECK_STRING (string); 3261 CHECK_STRING (string);
3251 3262
@@ -3257,10 +3268,7 @@ into shorter lines. */)
3257 allength += allength / MIME_LINE_LENGTH + 1 + 6; 3268 allength += allength / MIME_LINE_LENGTH + 1 + 6;
3258 3269
3259 /* We need to allocate enough room for decoding the text. */ 3270 /* We need to allocate enough room for decoding the text. */
3260 if (allength <= MAX_ALLOCA) 3271 SAFE_ALLOCA (encoded, char *, allength);
3261 encoded = (char *) alloca (allength);
3262 else
3263 encoded = (char *) xmalloc (allength);
3264 3272
3265 encoded_length = base64_encode_1 (SDATA (string), 3273 encoded_length = base64_encode_1 (SDATA (string),
3266 encoded, length, NILP (no_line_break), 3274 encoded, length, NILP (no_line_break),
@@ -3271,14 +3279,12 @@ into shorter lines. */)
3271 if (encoded_length < 0) 3279 if (encoded_length < 0)
3272 { 3280 {
3273 /* The encoding wasn't possible. */ 3281 /* The encoding wasn't possible. */
3274 if (length > MAX_ALLOCA) 3282 SAFE_FREE (allength);
3275 xfree (encoded);
3276 error ("Multibyte character in data for base64 encoding"); 3283 error ("Multibyte character in data for base64 encoding");
3277 } 3284 }
3278 3285
3279 encoded_string = make_unibyte_string (encoded, encoded_length); 3286 encoded_string = make_unibyte_string (encoded, encoded_length);
3280 if (allength > MAX_ALLOCA) 3287 SAFE_FREE (allength);
3281 xfree (encoded);
3282 3288
3283 return encoded_string; 3289 return encoded_string;
3284} 3290}
@@ -3397,6 +3403,7 @@ If the region can't be decoded, signal an error and don't modify the buffer. */
3397 int decoded_length; 3403 int decoded_length;
3398 int inserted_chars; 3404 int inserted_chars;
3399 int multibyte = !NILP (current_buffer->enable_multibyte_characters); 3405 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
3406 USE_SAFE_ALLOCA;
3400 3407
3401 validate_region (&beg, &end); 3408 validate_region (&beg, &end);
3402 3409
@@ -3409,10 +3416,7 @@ If the region can't be decoded, signal an error and don't modify the buffer. */
3409 working on a multibyte buffer, each decoded code may occupy at 3416 working on a multibyte buffer, each decoded code may occupy at
3410 most two bytes. */ 3417 most two bytes. */
3411 allength = multibyte ? length * 2 : length; 3418 allength = multibyte ? length * 2 : length;
3412 if (allength <= MAX_ALLOCA) 3419 SAFE_ALLOCA (decoded, char *, allength);
3413 decoded = (char *) alloca (allength);
3414 else
3415 decoded = (char *) xmalloc (allength);
3416 3420
3417 move_gap_both (XFASTINT (beg), ibeg); 3421 move_gap_both (XFASTINT (beg), ibeg);
3418 decoded_length = base64_decode_1 (BYTE_POS_ADDR (ibeg), decoded, length, 3422 decoded_length = base64_decode_1 (BYTE_POS_ADDR (ibeg), decoded, length,
@@ -3423,8 +3427,7 @@ If the region can't be decoded, signal an error and don't modify the buffer. */
3423 if (decoded_length < 0) 3427 if (decoded_length < 0)
3424 { 3428 {
3425 /* The decoding wasn't possible. */ 3429 /* The decoding wasn't possible. */
3426 if (allength > MAX_ALLOCA) 3430 SAFE_FREE (allength);
3427 xfree (decoded);
3428 error ("Invalid base64 data"); 3431 error ("Invalid base64 data");
3429 } 3432 }
3430 3433
@@ -3432,8 +3435,8 @@ If the region can't be decoded, signal an error and don't modify the buffer. */
3432 and delete the old. (Insert first in order to preserve markers.) */ 3435 and delete the old. (Insert first in order to preserve markers.) */
3433 TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg); 3436 TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg);
3434 insert_1_both (decoded, inserted_chars, decoded_length, 0, 1, 0); 3437 insert_1_both (decoded, inserted_chars, decoded_length, 0, 1, 0);
3435 if (allength > MAX_ALLOCA) 3438 SAFE_FREE (allength);
3436 xfree (decoded); 3439
3437 /* Delete the original text. */ 3440 /* Delete the original text. */
3438 del_range_both (PT, PT_BYTE, XFASTINT (end) + inserted_chars, 3441 del_range_both (PT, PT_BYTE, XFASTINT (end) + inserted_chars,
3439 iend + decoded_length, 1); 3442 iend + decoded_length, 1);
@@ -3458,15 +3461,13 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string,
3458 char *decoded; 3461 char *decoded;
3459 int length, decoded_length; 3462 int length, decoded_length;
3460 Lisp_Object decoded_string; 3463 Lisp_Object decoded_string;
3464 USE_SAFE_ALLOCA;
3461 3465
3462 CHECK_STRING (string); 3466 CHECK_STRING (string);
3463 3467
3464 length = SBYTES (string); 3468 length = SBYTES (string);
3465 /* We need to allocate enough room for decoding the text. */ 3469 /* We need to allocate enough room for decoding the text. */
3466 if (length <= MAX_ALLOCA) 3470 SAFE_ALLOCA (decoded, char *, length);
3467 decoded = (char *) alloca (length);
3468 else
3469 decoded = (char *) xmalloc (length);
3470 3471
3471 /* The decoded result should be unibyte. */ 3472 /* The decoded result should be unibyte. */
3472 decoded_length = base64_decode_1 (SDATA (string), decoded, length, 3473 decoded_length = base64_decode_1 (SDATA (string), decoded, length,
@@ -3478,8 +3479,7 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string,
3478 else 3479 else
3479 decoded_string = Qnil; 3480 decoded_string = Qnil;
3480 3481
3481 if (length > MAX_ALLOCA) 3482 SAFE_FREE (length);
3482 xfree (decoded);
3483 if (!STRINGP (decoded_string)) 3483 if (!STRINGP (decoded_string))
3484 error ("Invalid base64 data"); 3484 error ("Invalid base64 data");
3485 3485
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 84aa9f46d4d..3ffba0ba745 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -248,8 +248,46 @@ xg_get_image_for_pixmap (f, img, widget, old_widget)
248{ 248{
249 GdkPixmap *gpix; 249 GdkPixmap *gpix;
250 GdkPixmap *gmask; 250 GdkPixmap *gmask;
251 GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); 251 GdkDisplay *gdpy;
252
253 /* If we are on a one bit display, let GTK do all the image handling.
254 This seems to be the only way to make insensitive and activated icons
255 look good. */
256 if (x_screen_planes (f) == 1)
257 {
258 Lisp_Object specified_file = Qnil;
259 Lisp_Object tail;
260 extern Lisp_Object QCfile;
261
262 for (tail = XCDR (img->spec);
263 NILP (specified_file) && CONSP (tail) && CONSP (XCDR (tail));
264 tail = XCDR (XCDR (tail)))
265 if (EQ (XCAR (tail), QCfile))
266 specified_file = XCAR (XCDR (tail));
267
268 if (STRINGP (specified_file))
269 {
270
271 Lisp_Object file = Qnil;
272 struct gcpro gcpro1;
273 GCPRO1 (file);
252 274
275 file = x_find_image_file (specified_file);
276 /* We already loaded the image once before calling this
277 function, so this should not fail. */
278 xassert (STRINGP (file) != 0);
279
280 if (! old_widget)
281 old_widget = GTK_IMAGE (gtk_image_new_from_file (SDATA (file)));
282 else
283 gtk_image_set_from_file (old_widget, SDATA (file));
284
285 UNGCPRO;
286 return GTK_WIDGET (old_widget);
287 }
288 }
289
290 gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f));
253 gpix = gdk_pixmap_foreign_new_for_display (gdpy, img->pixmap); 291 gpix = gdk_pixmap_foreign_new_for_display (gdpy, img->pixmap);
254 gmask = img->mask ? gdk_pixmap_foreign_new_for_display (gdpy, img->mask) : 0; 292 gmask = img->mask ? gdk_pixmap_foreign_new_for_display (gdpy, img->mask) : 0;
255 293
@@ -262,6 +300,12 @@ xg_get_image_for_pixmap (f, img, widget, old_widget)
262 } 300 }
263 else 301 else
264 { 302 {
303 /* This is a workaround to make icons look good on pseudo color
304 displays. Apparently GTK expects the images to have an alpha
305 channel. If they don't, insensitive and activated icons will
306 look bad. This workaround does not work on monochrome displays,
307 and is not needed on true color/static color displays (i.e.
308 16 bits and higher). */
265 int x, y, width, height, rowstride, mask_rowstride; 309 int x, y, width, height, rowstride, mask_rowstride;
266 GdkPixbuf *icon_buf, *tmp_buf; 310 GdkPixbuf *icon_buf, *tmp_buf;
267 guchar *pixels; 311 guchar *pixels;
@@ -308,12 +352,9 @@ xg_get_image_for_pixmap (f, img, widget, old_widget)
308 } 352 }
309 } 353 }
310 354
311 g_object_unref (G_OBJECT (gmask));
312 g_object_unref (G_OBJECT (mask_buf)); 355 g_object_unref (G_OBJECT (mask_buf));
313 } 356 }
314 357
315 g_object_unref (G_OBJECT (gpix));
316
317 if (! old_widget) 358 if (! old_widget)
318 old_widget = GTK_IMAGE (gtk_image_new_from_pixbuf (icon_buf)); 359 old_widget = GTK_IMAGE (gtk_image_new_from_pixbuf (icon_buf));
319 else 360 else
@@ -322,6 +363,9 @@ xg_get_image_for_pixmap (f, img, widget, old_widget)
322 g_object_unref (G_OBJECT (icon_buf)); 363 g_object_unref (G_OBJECT (icon_buf));
323 } 364 }
324 365
366 g_object_unref (G_OBJECT (gpix));
367 if (gmask) g_object_unref (G_OBJECT (gmask));
368
325 return GTK_WIDGET (old_widget); 369 return GTK_WIDGET (old_widget);
326} 370}
327 371
diff --git a/src/keymap.c b/src/keymap.c
index fbf1263a71b..4c23977ef41 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -2273,7 +2273,11 @@ push_text_char_description (c, p)
2273 2273
2274DEFUN ("text-char-description", Ftext_char_description, Stext_char_description, 1, 1, 0, 2274DEFUN ("text-char-description", Ftext_char_description, Stext_char_description, 1, 1, 0,
2275 doc: /* Return a pretty description of file-character CHARACTER. 2275 doc: /* Return a pretty description of file-character CHARACTER.
2276Control characters turn into "^char", etc. */) 2276Control characters turn into "^char", etc. This differs from
2277`single-key-description' which turns them into "C-char".
2278Also, this function recognizes the 2**7 bit as the Meta character,
2279whereas `single-key-description' uses the 2**27 bit for Meta.
2280See Info node `(elisp)Describing Characters' for examples. */)
2277 (character) 2281 (character)
2278 Lisp_Object character; 2282 Lisp_Object character;
2279{ 2283{
diff --git a/src/lisp.h b/src/lisp.h
index 7e39313a7fc..aba3073dc68 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1203,7 +1203,10 @@ struct Lisp_Save_Value
1203 { 1203 {
1204 int type : 16; /* = Lisp_Misc_Save_Value */ 1204 int type : 16; /* = Lisp_Misc_Save_Value */
1205 unsigned gcmarkbit : 1; 1205 unsigned gcmarkbit : 1;
1206 int spacer : 15; 1206 int spacer : 14;
1207 /* If DOGC is set, POINTER is the address of a memory
1208 area containing INTEGER potential Lisp_Objects. */
1209 unsigned int dogc : 1;
1207 void *pointer; 1210 void *pointer;
1208 int integer; 1211 int integer;
1209 }; 1212 };
@@ -2498,6 +2501,7 @@ extern Lisp_Object make_float P_ ((double));
2498extern void display_malloc_warning P_ ((void)); 2501extern void display_malloc_warning P_ ((void));
2499extern int inhibit_garbage_collection P_ ((void)); 2502extern int inhibit_garbage_collection P_ ((void));
2500extern Lisp_Object make_save_value P_ ((void *, int)); 2503extern Lisp_Object make_save_value P_ ((void *, int));
2504extern void free_misc P_ ((Lisp_Object));
2501extern void free_marker P_ ((Lisp_Object)); 2505extern void free_marker P_ ((Lisp_Object));
2502extern void free_cons P_ ((struct Lisp_Cons *)); 2506extern void free_cons P_ ((struct Lisp_Cons *));
2503extern void init_alloc_once P_ ((void)); 2507extern void init_alloc_once P_ ((void));
@@ -3290,6 +3294,64 @@ extern Lisp_Object Vdirectory_sep_char;
3290 : Fcons ((el), (check))))) 3294 : Fcons ((el), (check)))))
3291 3295
3292 3296
3297/* SAFE_ALLOCA normally allocates memory on the stack, but if size is
3298 larger than MAX_ALLOCA, use xmalloc to avoid overflowing the stack. */
3299
3300#define MAX_ALLOCA 16*1024
3301
3302extern Lisp_Object safe_alloca_unwind (Lisp_Object);
3303
3304#define USE_SAFE_ALLOCA \
3305 int sa_count = SPECPDL_INDEX ()
3306
3307/* SAFE_ALLOCA allocates a simple buffer. */
3308
3309#define SAFE_ALLOCA(buf, type, size) \
3310 do { \
3311 if ((size) < MAX_ALLOCA) \
3312 buf = (type) alloca (size); \
3313 else \
3314 { \
3315 buf = (type) xmalloc (size); \
3316 record_unwind_protect (safe_alloca_unwind, \
3317 make_save_value (buf, 0)); \
3318 } \
3319 } while (0)
3320
3321/* SAFE_FREE frees xmalloced memory and enables GC as needed. */
3322
3323#define SAFE_FREE(size) \
3324 do { \
3325 if ((size) >= MAX_ALLOCA) \
3326 unbind_to (sa_count, Qnil); \
3327 } while (0)
3328
3329
3330/* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects. */
3331
3332#define SAFE_ALLOCA_LISP(buf, nelt) \
3333 do { \
3334 int size_ = (nelt) * sizeof (Lisp_Object); \
3335 if (size_ < MAX_ALLOCA) \
3336 buf = (Lisp_Object *) alloca (size_); \
3337 else \
3338 { \
3339 Lisp_Object arg_; \
3340 buf = (Lisp_Object *) xmalloc (size_); \
3341 arg_ = make_save_value (buf, nelt); \
3342 XSAVE_VALUE (arg_)->dogc = 1; \
3343 record_unwind_protect (safe_alloca_unwind, arg_); \
3344 } \
3345 } while (0)
3346
3347#define SAFE_FREE_LISP(nelt) \
3348 do { \
3349 if (((nelt) * sizeof (Lisp_Object)) >= MAX_ALLOCA) \
3350 unbind_to (sa_count, Qnil); \
3351 } while (0)
3352
3353
3354
3293#endif /* EMACS_LISP_H */ 3355#endif /* EMACS_LISP_H */
3294 3356
3295/* arch-tag: 9b2ed020-70eb-47ac-94ee-e1c2a5107d5e 3357/* arch-tag: 9b2ed020-70eb-47ac-94ee-e1c2a5107d5e
diff --git a/src/macterm.c b/src/macterm.c
index 360dccd4f16..04d6ec3be64 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -7018,7 +7018,7 @@ mac_get_emulated_btn ( UInt32 modifiers )
7018 int result = 0; 7018 int result = 0;
7019 if (!NILP (Vmac_emulate_three_button_mouse)) { 7019 if (!NILP (Vmac_emulate_three_button_mouse)) {
7020 int cmdIs3 = !EQ (Vmac_emulate_three_button_mouse, Qreverse); 7020 int cmdIs3 = !EQ (Vmac_emulate_three_button_mouse, Qreverse);
7021 if (modifiers & controlKey) 7021 if (modifiers & cmdKey)
7022 result = cmdIs3 ? 2 : 1; 7022 result = cmdIs3 ? 2 : 1;
7023 else if (modifiers & optionKey) 7023 else if (modifiers & optionKey)
7024 result = cmdIs3 ? 1 : 2; 7024 result = cmdIs3 ? 1 : 2;
@@ -7038,7 +7038,7 @@ mac_event_to_emacs_modifiers (EventRef eventRef)
7038 if (!NILP (Vmac_emulate_three_button_mouse) && 7038 if (!NILP (Vmac_emulate_three_button_mouse) &&
7039 GetEventClass(eventRef) == kEventClassMouse) 7039 GetEventClass(eventRef) == kEventClassMouse)
7040 { 7040 {
7041 mods &= ~(optionKey & cmdKey); 7041 mods &= ~(optionKey | cmdKey);
7042 } 7042 }
7043 return mac_to_emacs_modifiers (mods); 7043 return mac_to_emacs_modifiers (mods);
7044} 7044}
@@ -7237,40 +7237,6 @@ is_emacs_window (WindowPtr win)
7237} 7237}
7238 7238
7239static void 7239static void
7240do_window_activate (WindowPtr win)
7241{
7242 struct frame *f;
7243
7244 if (is_emacs_window (win))
7245 {
7246 f = mac_window_to_frame (win);
7247
7248 if (f)
7249 {
7250 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f), f);
7251 activate_scroll_bars (f);
7252 }
7253 }
7254}
7255
7256static void
7257do_window_deactivate (WindowPtr win)
7258{
7259 struct frame *f;
7260
7261 if (is_emacs_window (win))
7262 {
7263 f = mac_window_to_frame (win);
7264
7265 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
7266 {
7267 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f), 0);
7268 deactivate_scroll_bars (f);
7269 }
7270 }
7271}
7272
7273static void
7274do_app_resume () 7240do_app_resume ()
7275{ 7241{
7276 WindowPtr wp; 7242 WindowPtr wp;
@@ -8084,6 +8050,25 @@ XTread_socket (sd, expected, hold_quit)
8084 if (!mac_convert_event_ref (eventRef, &er)) 8050 if (!mac_convert_event_ref (eventRef, &er))
8085 switch (GetEventClass (eventRef)) 8051 switch (GetEventClass (eventRef))
8086 { 8052 {
8053 case kEventClassWindow:
8054 if (GetEventKind (eventRef) == kEventWindowBoundsChanged)
8055 {
8056 WindowPtr window_ptr;
8057 GetEventParameter(eventRef, kEventParamDirectObject,
8058 typeWindowRef, NULL, sizeof(WindowPtr),
8059 NULL, &window_ptr);
8060 f = mac_window_to_frame (window_ptr);
8061 if (f && !f->async_iconified)
8062 {
8063 int x, y;
8064
8065 x_real_positions (f, &x, &y);
8066 f->left_pos = x;
8067 f->top_pos = y;
8068 }
8069 SendEventToEventTarget (eventRef, toolbox_dispatcher);
8070 }
8071 break;
8087 case kEventClassMouse: 8072 case kEventClassMouse:
8088 if (GetEventKind (eventRef) == kEventMouseWheelMoved) 8073 if (GetEventKind (eventRef) == kEventMouseWheelMoved)
8089 { 8074 {
@@ -8135,6 +8120,14 @@ XTread_socket (sd, expected, hold_quit)
8135 SInt16 part_code; 8120 SInt16 part_code;
8136 int tool_bar_p = 0; 8121 int tool_bar_p = 0;
8137 8122
8123#if USE_CARBON_EVENTS
8124 /* This is needed to send mouse events like aqua window
8125 buttons to the correct handler. */
8126 if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
8127 != eventNotHandledErr)
8128 break;
8129#endif
8130
8138 if (dpyinfo->grabbed && last_mouse_frame 8131 if (dpyinfo->grabbed && last_mouse_frame
8139 && FRAME_LIVE_P (last_mouse_frame)) 8132 && FRAME_LIVE_P (last_mouse_frame))
8140 { 8133 {
@@ -8150,16 +8143,9 @@ XTread_socket (sd, expected, hold_quit)
8150 window_ptr = FrontWindow (); 8143 window_ptr = FrontWindow ();
8151 } 8144 }
8152 8145
8153#if USE_CARBON_EVENTS
8154 /* This is needed to send mouse events like aqua
8155 window buttons to the correct handler. */
8156 if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
8157 != eventNotHandledErr)
8158 break;
8159
8160 if (!is_emacs_window (window_ptr)) 8146 if (!is_emacs_window (window_ptr))
8161 break; 8147 break;
8162#endif 8148
8163 part_code = FindWindow (er.where, &window_ptr); 8149 part_code = FindWindow (er.where, &window_ptr);
8164 } 8150 }
8165 8151
@@ -8306,6 +8292,18 @@ XTread_socket (sd, expected, hold_quit)
8306#else /* not TARGET_API_MAC_CARBON */ 8292#else /* not TARGET_API_MAC_CARBON */
8307 DragWindow (window_ptr, er.where, &qd.screenBits.bounds); 8293 DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
8308#endif /* not TARGET_API_MAC_CARBON */ 8294#endif /* not TARGET_API_MAC_CARBON */
8295 /* Update the frame parameters. */
8296 {
8297 struct frame *f = mac_window_to_frame (window_ptr);
8298 if (f && !f->async_iconified)
8299 {
8300 int x, y;
8301
8302 x_real_positions (f, &x, &y);
8303 f->left_pos = x;
8304 f->top_pos = y;
8305 }
8306 }
8309 break; 8307 break;
8310 8308
8311 case inGoAway: 8309 case inGoAway:
@@ -8393,24 +8391,38 @@ XTread_socket (sd, expected, hold_quit)
8393 break; 8391 break;
8394 } 8392 }
8395 8393
8394 if (!is_emacs_window (window_ptr))
8395 break;
8396
8397 f = mac_window_to_frame (window_ptr);
8398
8396 if ((er.modifiers & activeFlag) != 0) 8399 if ((er.modifiers & activeFlag) != 0)
8397 { 8400 {
8401 /* A window has been activated */
8398 Point mouse_loc = er.where; 8402 Point mouse_loc = er.where;
8399 8403
8400 do_window_activate (window_ptr); 8404 x_new_focus_frame (dpyinfo, f);
8405 activate_scroll_bars (f);
8401 8406
8402 SetPortWindowPort (window_ptr); 8407 SetPortWindowPort (window_ptr);
8403 GlobalToLocal (&mouse_loc); 8408 GlobalToLocal (&mouse_loc);
8404 /* activateEvt counts as mouse movement, 8409 /* Window-activated event counts as mouse movement,
8405 so update things that depend on mouse position. */ 8410 so update things that depend on mouse position. */
8406 note_mouse_movement (mac_window_to_frame (window_ptr), 8411 note_mouse_movement (mac_window_to_frame (window_ptr),
8407 &mouse_loc); 8412 &mouse_loc);
8408 } 8413 }
8409 else 8414 else
8410 { 8415 {
8411 do_window_deactivate (window_ptr); 8416 /* A window has been deactivated */
8417 dpyinfo->grabbed = 0;
8418
8419 if (f == dpyinfo->x_focus_frame)
8420 {
8421 x_new_focus_frame (dpyinfo, 0);
8422 deactivate_scroll_bars (f);
8423 }
8424
8412 8425
8413 f = mac_window_to_frame (window_ptr);
8414 if (f == dpyinfo->mouse_face_mouse_frame) 8426 if (f == dpyinfo->mouse_face_mouse_frame)
8415 { 8427 {
8416 /* If we move outside the frame, then we're 8428 /* If we move outside the frame, then we're
diff --git a/src/print.c b/src/print.c
index 4b94d77e876..287e77edad1 100644
--- a/src/print.c
+++ b/src/print.c
@@ -658,7 +658,7 @@ If variable `temp-buffer-show-function' is non-nil, call it at the end
658to get the buffer displayed instead of just displaying the non-selected 658to get the buffer displayed instead of just displaying the non-selected
659buffer and calling the hook. It gets one argument, the buffer to display. 659buffer and calling the hook. It gets one argument, the buffer to display.
660 660
661usage: (with-output-to-temp-buffer BUFFNAME BODY ...) */) 661usage: (with-output-to-temp-buffer BUFNAME BODY ...) */)
662 (args) 662 (args)
663 Lisp_Object args; 663 Lisp_Object args;
664{ 664{
diff --git a/src/search.c b/src/search.c
index eba74f418ce..bb3f222e2c1 100644
--- a/src/search.c
+++ b/src/search.c
@@ -2543,15 +2543,20 @@ since only regular expressions have distinguished subexpressions. */)
2543 /* Adjust search data for this change. */ 2543 /* Adjust search data for this change. */
2544 { 2544 {
2545 int oldend = search_regs.end[sub]; 2545 int oldend = search_regs.end[sub];
2546 int oldstart = search_regs.start[sub];
2546 int change = newpoint - search_regs.end[sub]; 2547 int change = newpoint - search_regs.end[sub];
2547 int i; 2548 int i;
2548 2549
2549 for (i = 0; i < search_regs.num_regs; i++) 2550 for (i = 0; i < search_regs.num_regs; i++)
2550 { 2551 {
2551 if (search_regs.start[i] > oldend) 2552 if (search_regs.start[i] >= oldend)
2552 search_regs.start[i] += change; 2553 search_regs.start[i] += change;
2553 if (search_regs.end[i] > oldend) 2554 else if (search_regs.start[i] > oldstart)
2555 search_regs.start[i] = oldstart;
2556 if (search_regs.end[i] >= oldend)
2554 search_regs.end[i] += change; 2557 search_regs.end[i] += change;
2558 else if (search_regs.end[i] > oldstart)
2559 search_regs.end[i] = oldstart;
2555 } 2560 }
2556 } 2561 }
2557 2562
@@ -2620,8 +2625,11 @@ All the elements are markers or nil (nil if the Nth pair didn't match)
2620if the last match was on a buffer; integers or nil if a string was matched. 2625if the last match was on a buffer; integers or nil if a string was matched.
2621Use `store-match-data' to reinstate the data in this list. 2626Use `store-match-data' to reinstate the data in this list.
2622 2627
2623If INTEGERS (the optional first argument) is non-nil, always use integers 2628If INTEGERS (the optional first argument) is non-nil, always use
2624\(rather than markers) to represent buffer positions. 2629integers \(rather than markers) to represent buffer positions. In
2630this case, and if the last match was in a buffer, the buffer will get
2631stored as one additional element at the end of the list.
2632
2625If REUSE is a list, reuse it as part of the value. If REUSE is long enough 2633If REUSE is a list, reuse it as part of the value. If REUSE is long enough
2626to hold all the values, and if INTEGERS is non-nil, no consing is done. 2634to hold all the values, and if INTEGERS is non-nil, no consing is done.
2627 2635
@@ -2638,10 +2646,10 @@ Return value is undefined if the last search failed. */)
2638 2646
2639 prev = Qnil; 2647 prev = Qnil;
2640 2648
2641 data = (Lisp_Object *) alloca ((2 * search_regs.num_regs) 2649 data = (Lisp_Object *) alloca ((2 * search_regs.num_regs + 1)
2642 * sizeof (Lisp_Object)); 2650 * sizeof (Lisp_Object));
2643 2651
2644 len = -1; 2652 len = 0;
2645 for (i = 0; i < search_regs.num_regs; i++) 2653 for (i = 0; i < search_regs.num_regs; i++)
2646 { 2654 {
2647 int start = search_regs.start[i]; 2655 int start = search_regs.start[i];
@@ -2668,22 +2676,29 @@ Return value is undefined if the last search failed. */)
2668 /* last_thing_searched must always be Qt, a buffer, or Qnil. */ 2676 /* last_thing_searched must always be Qt, a buffer, or Qnil. */
2669 abort (); 2677 abort ();
2670 2678
2671 len = i; 2679 len = 2*(i+1);
2672 } 2680 }
2673 else 2681 else
2674 data[2 * i] = data [2 * i + 1] = Qnil; 2682 data[2 * i] = data [2 * i + 1] = Qnil;
2675 } 2683 }
2676 2684
2685 if (BUFFERP(last_thing_searched)
2686 && ! NILP (integers))
2687 {
2688 XSETBUFFER(data[len], last_thing_searched);
2689 len++;
2690 }
2691
2677 /* If REUSE is not usable, cons up the values and return them. */ 2692 /* If REUSE is not usable, cons up the values and return them. */
2678 if (! CONSP (reuse)) 2693 if (! CONSP (reuse))
2679 return Flist (2 * len + 2, data); 2694 return Flist (len, data);
2680 2695
2681 /* If REUSE is a list, store as many value elements as will fit 2696 /* If REUSE is a list, store as many value elements as will fit
2682 into the elements of REUSE. */ 2697 into the elements of REUSE. */
2683 for (i = 0, tail = reuse; CONSP (tail); 2698 for (i = 0, tail = reuse; CONSP (tail);
2684 i++, tail = XCDR (tail)) 2699 i++, tail = XCDR (tail))
2685 { 2700 {
2686 if (i < 2 * len + 2) 2701 if (i < len)
2687 XSETCAR (tail, data[i]); 2702 XSETCAR (tail, data[i]);
2688 else 2703 else
2689 XSETCAR (tail, Qnil); 2704 XSETCAR (tail, Qnil);
@@ -2692,8 +2707,8 @@ Return value is undefined if the last search failed. */)
2692 2707
2693 /* If we couldn't fit all value elements into REUSE, 2708 /* If we couldn't fit all value elements into REUSE,
2694 cons up the rest of them and add them to the end of REUSE. */ 2709 cons up the rest of them and add them to the end of REUSE. */
2695 if (i < 2 * len + 2) 2710 if (i < len)
2696 XSETCDR (prev, Flist (2 * len + 2 - i, data + i)); 2711 XSETCDR (prev, Flist (len - i, data + i));
2697 2712
2698 return reuse; 2713 return reuse;
2699} 2714}
@@ -2714,8 +2729,8 @@ LIST should have been created by calling `match-data' previously. */)
2714 if (!CONSP (list) && !NILP (list)) 2729 if (!CONSP (list) && !NILP (list))
2715 list = wrong_type_argument (Qconsp, list); 2730 list = wrong_type_argument (Qconsp, list);
2716 2731
2717 /* Unless we find a marker with a buffer in LIST, assume that this 2732 /* Unless we find a marker with a buffer or an explicit buffer
2718 match data came from a string. */ 2733 in LIST, assume that this match data came from a string. */
2719 last_thing_searched = Qt; 2734 last_thing_searched = Qt;
2720 2735
2721 /* Allocate registers if they don't already exist. */ 2736 /* Allocate registers if they don't already exist. */
@@ -2746,42 +2761,52 @@ LIST should have been created by calling `match-data' previously. */)
2746 2761
2747 search_regs.num_regs = length; 2762 search_regs.num_regs = length;
2748 } 2763 }
2749 }
2750
2751 for (i = 0; i < search_regs.num_regs; i++)
2752 {
2753 marker = Fcar (list);
2754 if (NILP (marker))
2755 {
2756 search_regs.start[i] = -1;
2757 list = Fcdr (list);
2758 }
2759 else
2760 {
2761 int from;
2762
2763 if (MARKERP (marker))
2764 {
2765 if (XMARKER (marker)->buffer == 0)
2766 XSETFASTINT (marker, 0);
2767 else
2768 XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer);
2769 }
2770
2771 CHECK_NUMBER_COERCE_MARKER (marker);
2772 from = XINT (marker);
2773 list = Fcdr (list);
2774 2764
2775 marker = Fcar (list); 2765 for (i = 0;; i++)
2776 if (MARKERP (marker) && XMARKER (marker)->buffer == 0) 2766 {
2777 XSETFASTINT (marker, 0); 2767 marker = Fcar (list);
2768 if (BUFFERP(marker))
2769 {
2770 XSETBUFFER(last_thing_searched, marker);
2771 break;
2772 }
2773 if (i >= length)
2774 break;
2775 if (NILP (marker))
2776 {
2777 search_regs.start[i] = -1;
2778 list = Fcdr (list);
2779 }
2780 else
2781 {
2782 int from;
2783
2784 if (MARKERP (marker))
2785 {
2786 if (XMARKER (marker)->buffer == 0)
2787 XSETFASTINT (marker, 0);
2788 else
2789 XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer);
2790 }
2791
2792 CHECK_NUMBER_COERCE_MARKER (marker);
2793 from = XINT (marker);
2794 list = Fcdr (list);
2795
2796 marker = Fcar (list);
2797 if (MARKERP (marker) && XMARKER (marker)->buffer == 0)
2798 XSETFASTINT (marker, 0);
2799
2800 CHECK_NUMBER_COERCE_MARKER (marker);
2801 search_regs.start[i] = from;
2802 search_regs.end[i] = XINT (marker);
2803 }
2804 list = Fcdr (list);
2805 }
2778 2806
2779 CHECK_NUMBER_COERCE_MARKER (marker); 2807 for (; i < search_regs.num_regs; i++)
2780 search_regs.start[i] = from; 2808 search_regs.start[i] = -1;
2781 search_regs.end[i] = XINT (marker); 2809 }
2782 }
2783 list = Fcdr (list);
2784 }
2785 2810
2786 return Qnil; 2811 return Qnil;
2787} 2812}
@@ -2790,6 +2815,7 @@ LIST should have been created by calling `match-data' previously. */)
2790 during the execution of a sentinel or filter. */ 2815 during the execution of a sentinel or filter. */
2791static int search_regs_saved; 2816static int search_regs_saved;
2792static struct re_registers saved_search_regs; 2817static struct re_registers saved_search_regs;
2818static Lisp_Object saved_last_thing_searched;
2793 2819
2794/* Called from Flooking_at, Fstring_match, search_buffer, Fstore_match_data 2820/* Called from Flooking_at, Fstring_match, search_buffer, Fstore_match_data
2795 if asynchronous code (filter or sentinel) is running. */ 2821 if asynchronous code (filter or sentinel) is running. */
@@ -2801,6 +2827,8 @@ save_search_regs ()
2801 saved_search_regs.num_regs = search_regs.num_regs; 2827 saved_search_regs.num_regs = search_regs.num_regs;
2802 saved_search_regs.start = search_regs.start; 2828 saved_search_regs.start = search_regs.start;
2803 saved_search_regs.end = search_regs.end; 2829 saved_search_regs.end = search_regs.end;
2830 saved_last_thing_searched = last_thing_searched;
2831 last_thing_searched = Qnil;
2804 search_regs.num_regs = 0; 2832 search_regs.num_regs = 0;
2805 search_regs.start = 0; 2833 search_regs.start = 0;
2806 search_regs.end = 0; 2834 search_regs.end = 0;
@@ -2823,7 +2851,8 @@ restore_match_data ()
2823 search_regs.num_regs = saved_search_regs.num_regs; 2851 search_regs.num_regs = saved_search_regs.num_regs;
2824 search_regs.start = saved_search_regs.start; 2852 search_regs.start = saved_search_regs.start;
2825 search_regs.end = saved_search_regs.end; 2853 search_regs.end = saved_search_regs.end;
2826 2854 last_thing_searched = saved_last_thing_searched;
2855 saved_last_thing_searched = Qnil;
2827 search_regs_saved = 0; 2856 search_regs_saved = 0;
2828 } 2857 }
2829} 2858}
diff --git a/src/w32fns.c b/src/w32fns.c
index a5f8c4b61f3..d3342f3ad6a 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -7749,7 +7749,8 @@ file_dialog_callback (hwnd, msg, wParam, lParam)
7749 { 7749 {
7750 OFNOTIFY * notify = (OFNOTIFY *)lParam; 7750 OFNOTIFY * notify = (OFNOTIFY *)lParam;
7751 /* Detect when the Filter dropdown is changed. */ 7751 /* Detect when the Filter dropdown is changed. */
7752 if (notify->hdr.code == CDN_TYPECHANGE) 7752 if (notify->hdr.code == CDN_TYPECHANGE
7753 || notify->hdr.code == CDN_INITDONE)
7753 { 7754 {
7754 HWND dialog = GetParent (hwnd); 7755 HWND dialog = GetParent (hwnd);
7755 HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD); 7756 HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD);
@@ -7763,8 +7764,10 @@ file_dialog_callback (hwnd, msg, wParam, lParam)
7763 } 7764 }
7764 else 7765 else
7765 { 7766 {
7766 CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD, 7767 /* Don't override default filename on init done. */
7767 ""); 7768 if (notify->hdr.code == CDN_TYPECHANGE)
7769 CommDlg_OpenSave_SetControlText (dialog,
7770 FILE_NAME_TEXT_FIELD, "");
7768 EnableWindow (edit_control, TRUE); 7771 EnableWindow (edit_control, TRUE);
7769 } 7772 }
7770 } 7773 }
@@ -7786,6 +7789,7 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
7786 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 7789 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
7787 char filename[MAX_PATH + 1]; 7790 char filename[MAX_PATH + 1];
7788 char init_dir[MAX_PATH + 1]; 7791 char init_dir[MAX_PATH + 1];
7792 int default_filter_index = 1; /* 1: All Files, 2: Directories only */
7789 7793
7790 GCPRO5 (prompt, dir, default_filename, mustmatch, file); 7794 GCPRO5 (prompt, dir, default_filename, mustmatch, file);
7791 CHECK_STRING (prompt); 7795 CHECK_STRING (prompt);
@@ -7809,9 +7813,7 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
7809 if (!file_name_only) 7813 if (!file_name_only)
7810 file_name_only = full_path_name; 7814 file_name_only = full_path_name;
7811 else 7815 else
7812 { 7816 file_name_only++;
7813 file_name_only++;
7814 }
7815 7817
7816 strncpy (filename, file_name_only, MAX_PATH); 7818 strncpy (filename, file_name_only, MAX_PATH);
7817 filename[MAX_PATH] = '\0'; 7819 filename[MAX_PATH] = '\0';
@@ -7836,6 +7838,15 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
7836 file_details.nMaxFile = sizeof (filename); 7838 file_details.nMaxFile = sizeof (filename);
7837 file_details.lpstrInitialDir = init_dir; 7839 file_details.lpstrInitialDir = init_dir;
7838 file_details.lpstrTitle = SDATA (prompt); 7840 file_details.lpstrTitle = SDATA (prompt);
7841
7842 /* If prompt starts with Dired, default to directories only. */
7843 /* A bit hacky, but there doesn't seem to be a better way to
7844 DTRT for dired. */
7845 if (strncmp (file_details.lpstrTitle, "Dired", 5) == 0)
7846 default_filter_index = 2;
7847
7848 file_details.nFilterIndex = default_filter_index;
7849
7839 file_details.Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR 7850 file_details.Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
7840 | OFN_EXPLORER | OFN_ENABLEHOOK); 7851 | OFN_EXPLORER | OFN_ENABLEHOOK);
7841 if (!NILP (mustmatch)) 7852 if (!NILP (mustmatch))
@@ -7848,7 +7859,7 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
7848 dostounix_filename (filename); 7859 dostounix_filename (filename);
7849 if (file_details.nFilterIndex == 2) 7860 if (file_details.nFilterIndex == 2)
7850 { 7861 {
7851 /* "Folder Only" selected - strip dummy file name. */ 7862 /* "Directories" selected - strip dummy file name. */
7852 char * last = strrchr (filename, '/'); 7863 char * last = strrchr (filename, '/');
7853 *last = '\0'; 7864 *last = '\0';
7854 } 7865 }
diff --git a/src/xdisp.c b/src/xdisp.c
index 41e00893c30..c95493d5aa3 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -6426,6 +6426,7 @@ add_to_log (format, arg1, arg2)
6426 char *buffer; 6426 char *buffer;
6427 int len; 6427 int len;
6428 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 6428 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6429 USE_SAFE_ALLOCA;
6429 6430
6430 /* Do nothing if called asynchronously. Inserting text into 6431 /* Do nothing if called asynchronously. Inserting text into
6431 a buffer may call after-change-functions and alike and 6432 a buffer may call after-change-functions and alike and
@@ -6442,10 +6443,12 @@ add_to_log (format, arg1, arg2)
6442 msg = Fformat (3, args); 6443 msg = Fformat (3, args);
6443 6444
6444 len = SBYTES (msg) + 1; 6445 len = SBYTES (msg) + 1;
6445 buffer = (char *) alloca (len); 6446 SAFE_ALLOCA (buffer, char *, len);
6446 bcopy (SDATA (msg), buffer, len); 6447 bcopy (SDATA (msg), buffer, len);
6447 6448
6448 message_dolog (buffer, len - 1, 1, 0); 6449 message_dolog (buffer, len - 1, 1, 0);
6450 SAFE_FREE (len);
6451
6449 UNGCPRO; 6452 UNGCPRO;
6450} 6453}
6451 6454